0Pricing
Lua Academy · レッスン

コルーチンによるAsync/Await

コルーチンをyield・resumeするasync()とawait()ヘルパーを作成します。

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

Async/Await の考え方

Async/await は、非同期操作を同期コードのように見せるプログラミングモデルです。Lua では、コルーチンが yield/resume の仕組みを提供するため、これを自然に実装できます。

await 関数

await(future) は現在のコルーチンを yield させ、Future の完了時にそれを再開するコールバックを保存します。

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

async 関数のラッパー

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

シンプルな Future オブジェクト

Future は保留中の結果を表します。後で完了させると、待機中のすべてのコルーチンを再開します。

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 の実践

内部では 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")

エラーの伝播

Future を介してエラーを渡します。操作に失敗した場合は、エラーフラグとエラーメッセージを伴ってコルーチンを再開します。

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

逐次実行と並列実行

依存する操作には await を順番に使用します。独立した操作には両方のコルーチンを起動し、結合用の Future を await します。

Promise.all パターン

複数の非同期タスクを実行し、カウンタを持つ 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

キャンセル

再開する前にコルーチンをキャンセル済みとして示すことで、キャンセルを実装します。コルーチンはそのフラグを確認して早期に戻ります。

I/O との統合

ノンブロッキング I/O と統合します。I/O 呼び出しがブロックしそうな場合は yield し、データが利用可能になったときに再開するコールバックを登録します。

コールバック方式との比較

コルーチンを使った Async/await は、入れ子になったコールバックよりもはるかに読みやすくなります。pcall を使ったエラー処理も、コールバックのエラーパラメータよりすっきりしています。

Async/Await に関する質問

コルーチンベースの非同期システムで、await(future) は何をしますか?

まとめ: コルーチンを使った Async/Await

非同期操作を、完了時に yield したコルーチンを再開する Future としてラップすることで、コルーチンを使った Async/await を実装します。その結果、実際にはノンブロッキングでありながら、逐次実行のように見えるコードになります。

よくある質問

「コルーチンによるAsync/Await」レッスンは無料ですか?

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

「コルーチンによるAsync/Await」で何を学びますか?

コルーチンをyield・resumeするasync()とawait()ヘルパーを作成します。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Lua Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「コルーチンによるAsync/Await」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLua Academyレッスンでコードを書いて実行できますか?

はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. シンプルなイベントループの構築
  2. コルーチンによるAsync/Await
  3. Promise風パターン
  4. luasocketによるノンブロッキングI/O
← Lua Academyに戻る