0Pricing
Lua Academy · レッスン

Promise風パターン

コルーチンとコールバックを使ってdeferred/promiseオブジェクトを実装します。

「Promise風パターン」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。

Promise とは

Promise は、将来利用可能になる値を表します。状態は pending(保留中)、fulfilled(値で履行済み)、または rejected(エラーで拒否済み)になります。

Lua の Promise テーブル

状態、値、コールバックのリストを持つテーブルとして、最小限の Promise を実装します。

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

resolve と reject

Promise を履行すると、すべての resolve コールバックを呼び出します。拒否すると、すべての reject コールバックを呼び出します。

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) メソッドは新しい Promise を返し、チェーンを可能にします。

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

コルーチン対応 Promise

Promise とコルーチンを組み合わせます。コルーチンは yield して Promise を待機し、Promise の resolve コールバックがコルーチンを再開します。

Promise.all

複数の Promise がすべて完了するまで待機します。

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

最初に完了した Promise(履行または拒否)の結果で解決します。

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

チェーン内のエラー伝播

チェーン内のいずれかのステップが例外を発生させると、エラーは次の拒否ハンドラに伝播します。未処理の rejection はチェーンの最後でログに記録する必要があります。

キャンセル可能な Promise

:cancel() メソッドを追加し、特別なキャンセル済み状態に遷移させることで、コールバックが実行されないようにします。

遅延評価される Promise

遅延 Promise は、最初の andThen が追加されたときにだけ処理を開始します。オプションの非同期操作に便利です。

Promise とコルーチンの使い分け

Promise はコールバックベースで、組み合わせて利用できます。コルーチンを使うと、非同期コードを同期コードのように記述できます。Lua では、コルーチン対応 Promise によって、Promise の組み合わせやすさと同期コードの可読性の両方を実現できます。

Promise に関する質問

Promise の andThen メソッドは何を返しますか?

まとめ: Promise に似たパターン

Promise は、pending、fulfilled、rejected の状態を持つ保留中の値を表します。andThen で操作をチェーンします。コルーチンと組み合わせると、Async/await 形式のコードを記述できます。並列処理の調整には all と race を使用します。

よくある質問

「Promise風パターン」レッスンは無料ですか?

はい。「Promise風パターン」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。

「Promise風パターン」で何を学びますか?

コルーチンとコールバックを使ってdeferred/promiseオブジェクトを実装します。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応の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に戻る