使用协程实现 Async/Await
创建 async() 和 await() 辅助函数,以挂起和恢复协程。
使用协程实现 Async/Await 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。
异步/等待思想
异步/等待是一种编程模型,其中异步操作看起来像同步代码。在 Lua 中,协程提供了 yield/resume 机制,可以自然地实现这一模型。
等待函数
await(future) 会让当前协程执行 yield,并保存一个回调;未来结果完成时,该回调会恢复协程。
local function await(future)
local co = coroutine.running()
future.onComplete = function(result)
coroutine.resume(co, result)
end
return coroutine.yield()
end异步函数包装器
async(fn) 会包装一个函数,使其在由调度器管理的新协程中运行。
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简单的未来结果对象
未来结果对象表示尚未产生的结果。稍后调用 complete,它就会恢复所有等待中的协程。
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等待的实际应用
编写看起来按顺序执行、但内部会执行 yield 和恢复操作的异步代码。
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")错误传播
通过未来结果对象传递错误:如果操作失败,就带着错误标志和错误消息恢复协程。
local function awaitSafe(future)
local co = coroutine.running()
future.onComplete = function(ok, result)
coroutine.resume(co, ok, result)
end
return coroutine.yield()
end顺序执行与并行执行
对于有依赖关系的操作,请按顺序使用 await。对于相互独立的操作,请启动两个协程,并等待一个合并结果对象。
Promise.all 模式
运行多个异步任务,并使用计数器形式的未来结果对象等待它们全部完成。
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取消
在恢复协程之前将其标记为已取消,即可实现取消。协程会检查该标志并提前返回。
与输入/输出集成
与非阻塞输入/输出集成:当输入/输出调用可能阻塞时,执行 yield,并注册一个回调,在数据可用时恢复协程。
与回调风格的比较
使用协程的异步/等待代码比嵌套回调可读性高得多。使用受保护调用处理错误,也比使用回调错误参数更简洁。
异步/等待问题
在基于协程的异步系统中,await(future) 会做什么?
回顾:使用协程实现异步/等待
将异步操作包装成未来结果对象,并在操作完成时恢复执行 yield 的协程,即可使用协程实现异步/等待。这样得到的代码看起来按顺序执行,实际上不会阻塞。
用 AI 导师学习 Lua — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 40
- 课程
- 159
常见问题解答
「使用协程实现 Async/Await」课时是免费的吗?
是的 — 「使用协程实现 Async/Await」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。
「使用协程实现 Async/Await」这节课中我会学到什么?
创建 async() 和 await() 辅助函数,以挂起和恢复协程。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Lua Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「使用协程实现 Async/Await」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Lua Academy 课中编写并运行代码吗?
能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 构建简单事件循环
- 使用协程实现 Async/Await
- 类似 Promise 的模式
- 使用 luasocket 实现非阻塞 I/O