AsyncGenerator
BaselineWidely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.
AsyncGenerator
オブジェクトは非同期ジェネレーター関数から返されるもので、非同期反復可能プロトコルと非同期イテレータープロトコルの両方を満たすものです。
非同期ジェネレーターメソッドは、常にPromise
オブジェクトを生成します。
AsyncGenerator
は隠しクラスのAsyncIterator
のサブクラスです。
試してみましょう
async function* foo() { yield await Promise.resolve("a"); yield await Promise.resolve("b"); yield await Promise.resolve("c");}let str = "";async function generate() { for await (const val of foo()) { str = str + val; } console.log(str);}generate();// Expected output: "abc"
コンストラクター
AsyncGenerator
コンストラクターはグローバルには利用できません。AsyncGenerator
のインスタンスは、非同期ジェネレーター関数から返される必要があります。
async function* createAsyncGenerator() { yield await Promise.resolve(1); yield await Promise.resolve(2); yield await Promise.resolve(3);}const asyncGen = createAsyncGenerator();asyncGen.next().then((res) => console.log(res.value)); // 1asyncGen.next().then((res) => console.log(res.value)); // 2asyncGen.next().then((res) => console.log(res.value)); // 3
実際、AsyncGenerator
コンストラクターに対応するJavaScriptのエンティティはありません。非同期ジェネレーター関数によって生成されるすべてのオブジェクトによって共有されるプロトタイプオブジェクトである隠しオブジェクトがあるだけです。このオブジェクトはクラスのように見せるためにAsyncGenerator.prototype
というスタイルで呼ばれることが多いのですが、AsyncGeneratorFunction.prototype.prototype
と呼ぶほうが適切でしょう。なぜならAsyncGeneratorFunction
は実際の JavaScript エンティティであるからです。
インスタンスプロパティ
これらのプロパティはAsyncGenerator.prototype
で定義されており、すべてのAsyncGenerator
インスタンスで共有されています。
AsyncGenerator.prototype.constructor
インスタンスオブジェクトを作成したコンストラクター関数。
AsyncGenerator
インスタンスの場合、初期値はAsyncGeneratorFunction.prototype
です。メモ:
AsyncGenerator
は生成した非同期ジェネレーター関数を格納しているわけではありません。AsyncGenerator.prototype[Symbol.toStringTag]
@@toStringTag
プロパティの初期値は、文字列"AsyncGenerator"
です。このプロパティはObject.prototype.toString()
で使用されます。
インスタンスメソッド
親であるAsyncIterator
からインスタンスメソッドを継承しています。
AsyncGenerator.prototype.next()
AsyncGenerator.prototype.return()
ジェネレータ本体に現在の停止位置に
return
文を挿入したかのように動作します。try...finally
ブロックと組み合わせるとジェネレーターを終了し、クリーンアップタスクを実行することができます。AsyncGenerator.prototype.throw()
ジェネレーター本体の現在の停止位置に
throw
文が挿入されたかのように動作します。これは、ジェネレーターにエラー状態を通知し、エラーを処理するか、クリーンアップを実行して自身を終了させることができます。
例
非同期ジェネレーターの反復処理
次の例では、非同期ジェネレーターを反復処理し、時間間隔が短くなるごとに 1~6 の値をコンソールに出力しています。時刻が変わるたびにプロミスが生成されますが、それはfor await...of
ループの中で自動的に解決されることに注意してください。
// 非同期タスクです。実際にはもっと有益なことを使用していることを// 想定してください。function delayedValue(time, value) { return new Promise((resolve /*, reject*/) => { setTimeout(() => resolve(value), time); });}async function* generate() { yield delayedValue(2000, 1); yield delayedValue(100, 2); yield delayedValue(500, 3); yield delayedValue(250, 4); yield delayedValue(125, 5); yield delayedValue(50, 6); console.log("All done!");}async function main() { for await (const value of generate()) { console.log("value", value); }}main().catch((e) => console.error(e));
仕様書
Specification |
---|
ECMAScript® 2026 Language Specification # sec-asyncgenerator-objects |