Lua Nested Coroutine Yields
A nested coroutine yield is a yield called from a function that a coroutine called. The yield still reaches the resumer, even though the yielding code sits several calls deep.
A yield inside a helper reaches the resumer
The coroutine calls a helper, and the helper yields. The resume still returns the yielded value.
local function helper()
coroutine.yield("from helper")
print("helper done")
end
local co = coroutine.create(function()
helper()
end)
local ok, value = coroutine.resume(co)
print(value)
coroutine.resume(co)Yields cross two levels of calls
The outer function calls the middle one, which calls the inner one, and the inner one yields. The value still arrives at the resumer.
local function inner()
coroutine.yield("deep")
end
local function middle()
inner()
end
local function outer()
middle()
print("outer done")
end
local co = coroutine.create(outer)
local ok, value = coroutine.resume(co)
print(value)
coroutine.resume(co)Nested yields arrive in order
A helper yields three values in a loop. The main code resumes three times and prints each value as it arrives.
local function helper()
for i = 1, 3 do
coroutine.yield(i * 10)
end
end
local co = coroutine.create(function()
helper()
end)
for _ = 1, 3 do
local ok, value = coroutine.resume(co)
print(value)
endExample
local function double(n)
coroutine.yield(n * 2)
end
local function process(values)
for _, v in ipairs(values) do
double(v)
end
end
local co = coroutine.create(function()
process({1, 2, 3})
end)
while coroutine.status(co) ~= "dead" do
local ok, value = coroutine.resume(co)
if value ~= nil then
print(value)
end
endKey points
- Nested call: a function called by another function inside the same coroutine.
- Yield crossing: a yield inside a nested function suspends the whole coroutine, not just that function.
- Resumer: the code outside the coroutine that receives the yielded value on resume.
- Return path: when the coroutine is resumed again, the nested function continues right after its yield.
- Order: values yielded from nested calls arrive at the resumer in the order the yields run.
In this example, the coroutine calls process, which calls double for each input value. Each double call yields its doubled value across two call levels to the main loop, which prints 2, 4, then 6 in order.
Note
the call stack is kept while the coroutine is suspended, so locals in every level survive the yield.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
A coroutine calls function A, A calls function B, and B yields "x". Who receives "x"?