コルーチンによる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()
endasync 関数のラッパー
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
endawait の実践
内部では 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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- シンプルなイベントループの構築
- コルーチンによるAsync/Await
- Promise風パターン
- luasocketによるノンブロッキングI/O