Lua Academy · Lesson

Async/Await with Coroutines

Create async() and await() helpers that yield and resume coroutines.

Lesson 2 of 413 steps

Async/Await with Coroutines is a free Lua Academy lesson on CoddyKit. This is lesson 2 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Lua Academy learning path, and your progress syncs across the web and the CoddyKit app. The Lua Academy course includes 4 lessons in total.

The Async/Await Idea

Async/await is a programming model where asynchronous operations look like synchronous code. In Lua, coroutines provide the yield/resume mechanism to implement this naturally.

await Function

await(future) yields the current coroutine and stores a callback that resumes it when the future completes.

local function await(future)
  local co = coroutine.running()
  future.onComplete = function(result)
    coroutine.resume(co, result)
  end
  return coroutine.yield()
end

async Function Wrapper

async(fn) wraps a function so it runs in a new coroutine managed by the scheduler.

local function async(fn)
  return function(...)
    local co = coroutine.create(fn)
    local ok, err = coroutine.resume(co, ...)
    if not ok then print("async error:", err) end
    return co
  end
end

Simple Future Object

A future represents a pending result. Complete it later and it resumes all waiting coroutines.

local function newFuture()
  local f = {done=false, value=nil, waiters={}}
  f.complete = function(val)
    f.done = true; f.value = val
    for _, cb in ipairs(f.waiters) do cb(val) end
  end
  f.andThen = function(cb)
    if f.done then cb(f.value)
    else f.waiters[#f.waiters+1] = cb end
  end
  return f
end

await in Practice

Write sequential-looking async code that internally yields and resumes.

local fetchData = async(function(url)
  local result = await(httpGet(url))  -- yields
  local parsed = await(parseJSON(result))  -- yields again
  print("Got:", parsed.name)
end)
fetchData("http://example.com/api")

Error Propagation

Pass errors through the future: if the operation fails, resume the coroutine with an error flag and the error message.

local function awaitSafe(future)
  local co = coroutine.running()
  future.onComplete = function(ok, result)
    coroutine.resume(co, ok, result)
  end
  return coroutine.yield()
end

Sequential vs Parallel

Use await in sequence for dependent operations. For independent operations, spawn both coroutines and await a join future.

Promise.all Pattern

Run multiple async tasks and wait for all to complete using a counter future.

local function all(futures)
  local results = {}
  local count = #futures
  local combined = newFuture()
  for i, f in ipairs(futures) do
    f:andThen(function(v)
      results[i] = v
      count = count - 1
      if count == 0 then combined.complete(results) end
    end)
  end
  return combined
end

Cancellation

Implement cancellation by flagging the coroutine as cancelled before resuming it. The coroutine checks the flag and returns early.

Integration with I/O

Integrate with non-blocking I/O: when an I/O call would block, yield and register a callback to resume when data is available.

Comparison to Callback Style

Async/await with coroutines is dramatically more readable than nested callbacks. Error handling with pcall is also cleaner than callback error parameters.

Async/Await Question

What does await(future) do in a coroutine-based async system?

Recap: Async/Await with Coroutines

Implement async/await with coroutines by wrapping async ops as futures that resume the yielded coroutine on completion. The result is sequential-looking code that is actually non-blocking.

Free to start

Learn Lua with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
40
Lessons
159

Frequently Asked Questions

Is the “Async/Await with Coroutines” lesson free?

Yes — any 3 lessons of the Lua Academy learning path, including “Async/Await with Coroutines”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Lua Academy course includes 4 lessons in total.

What will I learn in “Async/Await with Coroutines”?

Create async() and await() helpers that yield and resume coroutines. You practise Lua Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Lua Academy?

No prior experience is required. Lua Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 2 of 4.

How long does the “Async/Await with Coroutines” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Lua Academy lesson?

Yes. Every Lua Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Building a Simple Event Loop
  2. Async/Await with Coroutines
  3. Promise-Like Patterns
  4. Non-Blocking I/O with luasocket
← Back to Lua Academy