コンテンツにスキップ

ストリーム

Streams APIは、JavaScriptがプログラム的にデータのストリームにアクセスし、処理することを可能にするウェブ標準APIです。

ワーカーは、event.respondWith()に応答ボディ全体を準備する必要はありません。フロントマター(つまり、HTTPステータスラインとヘッダー)を送信した後に応答ボディをストリーミングするためにTransformStreamを使用できます。これにより、次のことを最小限に抑えることができます:

  • 訪問者のタイム・トゥ・ファースト・バイト。
  • ワーカーで行われるバッファリング。

バッファリングを最小限に抑えることは、ワーカーのメモリ制限を超える応答ボディを処理または変換する場合に特に重要です。これらのケースでは、ストリーミングが唯一の実装戦略です。

ワーカーは、ReadableStreamをボディとして使用してResponseオブジェクトを作成できます。ReadableStreamを通じて提供されるデータは、利用可能になるとクライアントにストリーミングされます。

export default {
async fetch(request, env, ctx) {
// オリジンサーバーから取得します。
let response = await fetch(request);
// ... そして、その処理が実行されている間に応答を提供します。
return new Response(response.body, response);
}
}

TransformStreamReadableStream.pipeTo()メソッドを使用して、ストリーミング中に応答ボディを変更できます:

export default {
async fetch(request, env, ctx) {
// オリジンサーバーから取得します。
let response = await fetch(request);
let { readable, writable } = new TransformStream({
transform(chunk, controller) {
controller.enqueue(modifyChunkSomehow(chunk));
}
});
// ボディのポンピングを開始します。注意:awaitはしません!
response.body.pipeTo(writable);
// ... そして、その処理が実行されている間に応答を提供します。
return new Response(readable, response);
}
}

この例では、response.body.pipeTo(writable)を呼び出しますが、awaitはしません。これは、fetchAndStream()関数の残りの進行をブロックしないようにするためです。応答が完了するか、クライアントが切断されるまで非同期に実行され続けます。

ランタイムは、応答がクライアントに返された後も関数(response.body.pipeTo(writable))を実行し続けることができます。この例では、サブリクエストの応答ボディを最終的な応答ボディにポンピングします。ただし、ボディにプレフィックスやサフィックスを追加したり、何らかの方法で処理したりするなど、より複雑なロジックを使用することもできます。


一般的な問題


関連リソース