0Pricing
JavaScript Academy · レッスン

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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Readable Streams
  2. fetch レスポンスのストリーミング
  3. Transform Streams
  4. バックプレッシャーとパイプ処理
← JavaScript Academyに戻る