fetch レスポンスのストリーミング
大きなレスポンスを到着したそばから処理します。
「fetch レスポンスのストリーミング」はCoddyKit上の無料JavaScript Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJavaScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 JavaScript Academyコースには全4レッスンが含まれています。
レスポンスはストリーム
fetch の Response は、response.body を通じて本文を ReadableStream として公開します。ペイロード全体の読み込みを待たずに、到着したバイトを処理できます。
const res = await fetch("/big-file");
const stream = res.body; // ReadableStream of Uint8Array本文ストリームを読み取る
response.body は Uint8Array のチャンクを返します。リーダーを取得し、通常の ReadableStream と同じようにループします。
const reader = res.body.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) break;
console.log("received", value.length, "bytes");
}ダウンロードの進行状況を追跡する
Content-Length ヘッダーと受信済みバイト数を組み合わせると、進行状況バーを表示できます。
const total = +res.headers.get("Content-Length");
let loaded = 0;
while (true) {
const { value, done } = await reader.read();
if (done) break;
loaded += value.length;
console.log(Math.round((loaded / total) * 100) + "%");
}バイトをテキストにデコードする
TextDecoder を使って、バイトのチャンクを文字列に変換します。チャンクをまたいで分割されたマルチバイト文字を正しくデコードするには、{ stream: true } を渡します。
const decoder = new TextDecoder();
let text = "";
while (true) {
const { value, done } = await reader.read();
if (done) break;
text += decoder.decode(value, { stream: true });
}TextDecoderStream を使う
さらに簡単な方法として、バイトストリームを TextDecoderStream にパイプすると、文字列のストリームを直接取得できます。
const textStream = res.body.pipeThrough(new TextDecoderStream());
for await (const chunk of textStream) {
console.log(chunk);
}NDJSON を解析する
改行区切り JSON は、1行に1つのオブジェクトをストリームします。テキストをバッファーに蓄積し、完全な行ができた時点で出力します。
let buffer = "";
for await (const chunk of textStream) {
buffer += chunk;
let nl;
while ((nl = buffer.indexOf("\n")) >= 0) {
const line = buffer.slice(0, nl);
buffer = buffer.slice(nl + 1);
if (line) console.log(JSON.parse(line));
}
}LLM トークンをストリーミングする
このパターンはストリーミング AI チャットを支えます。各チャンクはトークンまたはイベントであり、到着した瞬間に描画することで、リアルタイムのタイピング効果を実現します。
fetch ストリームを中止する
AbortSignal を fetch に渡し、controller.abort() を呼び出すと、長時間のストリームを安全に停止できます。
const controller = new AbortController();
fetch("/stream", { signal: controller.signal });
// later:
controller.abort();ストリームのエラーを処理する
ストリームの途中でネットワーク障害が発生すると、read() の Promise は reject されます。ループを try/catch で囲み、中断を処理してください。
try {
while (true) {
const { value, done } = await reader.read();
if (done) break;
}
} catch (err) {
console.log("stream interrupted", err);
}ストリーミングを使わない場合
レスポンスが小さい場合は、res.json() または res.text() のほうが簡単です。ペイロードが大きい、段階的に到着する、またはサイズが決まっていない場合にストリーミングを使います。
レスポンス本文は1回しか使えない
response.body は1回しか読み取れません。2回必要な場合(たとえばキャッシュする場合)は、読み取る前に res.clone() を呼び出してください。
const copy = res.clone();
await res.body.getReader().read();
// copy still readableクイックチェック
fetch のストリーミングをテストします。
まとめ: fetch のストリーミング
response.body をチャンク単位で読み取り、進行状況を追跡し、TextDecoder と TextDecoderStream でバイトをデコードし、NDJSON を解析し、AbortController で中止し、エラーを処理しました。次は変換ストリームです。
よくある質問
「fetch レスポンスのストリーミング」レッスンは無料ですか?
はい。「fetch レスポンスのストリーミング」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、JavaScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 JavaScript Academyコースには全4レッスンが含まれています。
「fetch レスポンスのストリーミング」で何を学びますか?
大きなレスポンスを到着したそばから処理します。 ブラウザで直接実行するハンズオンコードでJavaScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
JavaScript Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJavaScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「fetch レスポンスのストリーミング」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJavaScript Academyレッスンでコードを書いて実行できますか?
はい。すべてのJavaScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Readable Streams
- fetch レスポンスのストリーミング
- Transform Streams
- バックプレッシャーとパイプ処理