フェッチ付きプログレスインジケーター


簡単なヒント:私は、サービスワーカーのためのコンテンツをシードするために大きなファイルをダウンロードできる方法を示しました.あなたは十分に速く見える場合は、進行状況インジケータが表示されます.(小さなファイルについては、瞬きしてください.👀
コードはかなり簡単です.単純なasyncから始めましょうfetch :
async function downloadFile(url) {
  const response = await fetch(url);
  const arrayBuffer = await response.arrayBuffer();
  const bytes = new Uint8Array(arrayBuffer);
  // do something with bytes
}
The arrayBuffer コールは、バイトを返す前に全体のターゲットがダウンロードされるまで待ちます.代わりに、ファイルの'塊'を消費することができます(私たちは、時間の経過とともにファイルの一部を取得するので、パーセンテージの感覚を得るために).

ヘッダをチェック
まず最初に、私たちの応答の“Content - Length”ヘッダーを読みます.これは、サーバーがデータの前に私たちを送ってくるものです.
  const response = await fetch(url);
  const length = response.headers.get('Content-Length');
  if (!length) {
    // something was wrong with response, just give up
    return await response.arrayBuffer();
  }
有効なヘッダーがないならば、応答の何かが間違っています、あるいは、サーバーはそれがどれくらいあるかについて、我々に話しませんでした.あなたは、ちょうどあなたが前にしていたことに戻ることができます.

チャンク
データが到着すると、ブラウザはリモートサーバーからバイトのチャンクを受け取ります.私たちはトータルレスポンスがどれくらい長くなるかを知っているので、バッファを準備することができます.
  const array = new Uint8Array(length);
  let at = 0;  // to index into the array
そして、読者をつかむ.
  const reader = response.body.getReader();
今、我々は我々がどこにいるかを格納することができますat ), そして、新しいチャンクを出力に挿入します.
  for (;;) {
    const {done, value} = await reader.read();
    if (done) {
      break;
    }
    array.set(value, at);
    at += value.length;
  }
  return array;
上記のループ内では、進捗状況をパーセンテージとしてログ出力できます.
    progress.textContent = `${(at / length).toFixed(2)}%`;
それから、配列を返します.

フィン
20👋