AsyncGenerator
Baseline Widely 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
のサブクラスです。
試してみましょう
コンストラクター
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)); // 1
asyncGen.next().then((res) => console.log(res.value)); // 2
asyncGen.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[@@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 Language Specification # sec-asyncgenerator-objects |
ブラウザーの互換性
BCD tables only load in the browser