0Pricing
Lua Academy · 课时

类似 Promise 的模式

使用协程和回调实现延迟对象或 Promise 对象。

类似 Promise 的模式 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。

什么是承诺对象

承诺对象表示未来可用的值。它可以处于待定、已兑现(带有一个值)或已拒绝(带有一个错误)状态。

Lua 承诺表

将最小承诺对象实现为一个表,其中包含状态、值和回调列表。

local function newPromise()
  return {
    state    = "pending",
    value    = nil,
    _resolve = {},
    _reject  = {},
  }
end

解析与拒绝

兑现承诺对象会调用所有解析回调。拒绝承诺对象会调用所有拒绝回调。

local function resolve(p, value)
  if p.state ~= "pending" then return end
  p.state = "fulfilled"; p.value = value
  for _, cb in ipairs(p._resolve) do cb(value) end
end
local function reject(p, reason)
  if p.state ~= "pending" then return end
  p.state = "rejected"; p.value = reason
  for _, cb in ipairs(p._reject) do cb(reason) end
end

andThen 链式调用

:andThen(onFulfill, onReject) 方法会返回一个新的承诺对象,从而支持链式调用。

function promise:andThen(onFulfill, onReject)
  local next = newPromise()
  self._resolve[#self._resolve+1] = function(v)
    local ok, result = pcall(onFulfill, v)
    if ok then resolve(next, result)
    else reject(next, result) end
  end
  if onReject then
    self._reject[#self._reject+1] = function(e)
      local ok, result = pcall(onReject, e)
      if ok then resolve(next, result)
      else reject(next, result) end
    end
  end
  return next
end

由协程支持的承诺对象

将承诺对象与协程结合:协程通过执行 yield 等待承诺对象,而承诺对象的解析回调会恢复该协程。

Promise.all

等待多个承诺对象全部完成。

local function all(promises)
  local results = {}
  local count = #promises
  local combined = newPromise()
  for i, p in ipairs(promises) do
    p:andThen(function(v)
      results[i] = v; count = count - 1
      if count == 0 then resolve(combined, results) end
    end, function(e) reject(combined, e) end)
  end
  return combined
end

Promise.race

使用最先完成的承诺对象(无论兑现还是拒绝)来完成结果。

local function race(promises)
  local combined = newPromise()
  for _, p in ipairs(promises) do
    p:andThen(
      function(v) resolve(combined, v) end,
      function(e) reject(combined, e) end
    )
  end
  return combined
end

链中的错误传播

如果链中的任何一步抛出错误,错误就会传播到下一个拒绝处理器。未处理的拒绝应在链的末尾记录日志。

可取消的承诺对象

添加一个 :cancel() 方法,将状态转换为特殊的已取消状态,从而阻止回调执行。

惰性承诺对象

惰性承诺对象只有在首次附加 andThen 时才开始执行工作,适合可选的异步操作。

何时使用承诺对象,何时使用协程

承诺对象基于回调并且可以组合。协程可以让异步代码看起来像同步代码。在 Lua 中,由协程支持的承诺对象兼具两者的优点:承诺对象的可组合性和同步代码的可读性。

承诺对象问题

承诺对象的 andThen 方法会返回什么?

回顾:类似承诺对象的模式

承诺对象表示处于待定、已兑现或已拒绝状态的值。使用 andThen 链接操作。将承诺对象与协程结合,以编写异步/等待风格的代码。使用全部操作和竞速操作进行并行协调。

常见问题解答

「类似 Promise 的模式」课时是免费的吗?

是的 — 「类似 Promise 的模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。

「类似 Promise 的模式」这节课中我会学到什么?

使用协程和回调实现延迟对象或 Promise 对象。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Lua Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「类似 Promise 的模式」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Lua Academy 课中编写并运行代码吗?

能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 构建简单事件循环
  2. 使用协程实现 Async/Await
  3. 类似 Promise 的模式
  4. 使用 luasocket 实现非阻塞 I/O
← 返回 Lua Academy