FetchAPIとReadableSTreamについて解説してみた!

XMLHttpRequestとは

サーバーとWebページの更新なしにデータのやり取りを実現できる。
同期的・非同期的かはオプションとして選択でき、
テキストデータだけでなくバイナリデータのやり取りも可能である。

Fetch APIとは

fetchではXMLHTTPRequestと比べてモダンなAPIだと言われている。
fetchで取得するデータはresponseとされ、
text,ArrayBuffer,json,formData,blobなど様々なファイルタイプで返してくれます。

developer.mozilla.org

responseの中身

responseの中身に含まれるのは、
header,status,url,type,bodyなど
特にbodyではreadbablestream読み取り専用のGetterが用意されています。

ReadableStream

ReadableStreamとは正確に言えばInterfaceです。
つまりバイトデータが格納されていても読み取り可能なStreamとなっています。
ReadableStreamからデータを読み取ることは可能か?
小規模データならこれで可能。

fetch('data.text')
  .then((response) => response.body.getReader()) 

大容量のデータとなると話が変わってくるようです。

ReadableStreamで大容量データを読み込むには

ここで想定していたのは100MBくらいのデータ読み込み。
上記のコードでは細切れのデータしか読み取れず、
大容量データを読み込むにはある程度工夫をしないといけないようです。

ReadableStream.read()はPromise/<ファイルを次々読み込む関数>で返されるようですが、
{ done , value }の引数があり、
done=trueになるまで読み込みを続け、
valueデコーダに渡すことによりデータを生成するようです。

sbfl.net

typescriptで書いてみました。

const reader:any = result.body.getReader();

return new ReadableStream({
   start(controller) {
        const push () => {
            // done=boolean, value=Uint8array
            reader.read().then({ done,value } :any) => {
                 // まだ読み取るデータがあるか
                 if (done) {
                    console.log('next data?  (else):',done)
                    // データ取得が完了
                    controller.close()
                    return;
                }
           // データを取得し終えたのでブラウザに送信
           controller.enqueue(value);
           return push();
           });
       };
      return push();
      }
   });