「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > Streams API が Web 開発者にとって大きな変革となる理由

Streams API が Web 開発者にとって大きな変革となる理由

2024 年 11 月 8 日に公開
ブラウズ:812

まず、Web 上でデータがどのように送信されるかを説明しましょう。単一の連続ストリームとして送信されるわけではありません。代わりに、より小さなチャンクに分割されます。受信側では、すべてのデータを受信した後、コンシューマまたはアプリケーションがこれらのチャンクを正しい順序と形式で再組み立てする必要があります。このプロセスは、画像、ビデオ、その他の比較的大きなデータ型に対して自動的に行われます。

Why the Streams API is a Game-Changer for Web Developers

つまり、Streams API が提供するのは、完全なデータが利用可能になるのを待つ代わりに、

    データは消費者段階でチャンクとして受信されるため、リアルタイムで処理されます。これは非常に便利で、この記事で示す例のような大量のデータを扱う場合には非常に不可欠です。
  1. また、データをストリームとして扱うこともできます。これは、特定のタイプのチャンクを送信する場合にバックエンド側で便利であり、同様のワーカーを使用してネットワーク経由で大きなファイルを送信する場合にフロントエンドで役立ちます。」
改訂されたテキスト: 「Streams API が提供するのは、データセット全体が利用可能になるのを待つのではなく、到着したデータを処理する方法です。主な利点は次の 2 つです:

    リアルタイム データ処理: チャンクで受信したデータをリアルタイムで処理できます。この機能は、この記事で説明する例のように、大量のデータを処理する場合に非常に重要です。 (この記事は前半部分に焦点を当てています)
  1. ストリームベースのデータ管理: Streams API を使用すると、データを連続ストリームとして扱うことができます。これは、バックエンドで特定のチャンクでデータを送信する場合や、フロントエンドで Web ワーカーを使用して大きなファイルを効率的にアップロードする場合に役立ちます。
まず、Fetch API を使用してデータを受信する従来の方法と、新しい Streams API アプローチを比較してみましょう。

フェッチ API を使用した従来のアプローチ

fetch("url") .then((応答) => { // 最終データを受け取る前に中間ステップがあることに注意してください // 実際に何を受け取るか見てみましょう console.log(response.body);応答.text()を返します; }) .then((data) => { // データを使用して演算を実行します });
fetch("url") .then((response) => {
// Note that there is a middle step before we receive the final data
// Let's see what we actually receive
console.log(response.body); return response.text(); }) .then((data) => { // Perform operations with the data
});
この例では、response.body は ReadableStream オブジェクトです:


ReadableStream { ロック済み: false、状態: '読み取り可能'、BYOB をサポート: true }
fetch("url") .then((response) => {
// Note that there is a middle step before we receive the final data
// Let's see what we actually receive
console.log(response.body); return response.text(); }) .then((data) => { // Perform operations with the data
});
ここでは、Streams API の最初のコンポーネントである ReadableStream に遭遇します。 ReadableStream コンストラクターは、読み取り可能なストリーム オブジェクトを作成して返します。これにより、ストリーミング データをより効率的に処理できるようになります。このコンストラクターを使用すると、データセット全体が利用可能になるのを待つのではなく、データをチャンク単位で管理できます。


{ arrayBuffer(): Promise; blob(): Promise; formData(): Promise; json(): Promise; text(): Promise; }
fetch("url") .then((response) => {
// Note that there is a middle step before we receive the final data
// Let's see what we actually receive
console.log(response.body); return response.text(); }) .then((data) => { // Perform operations with the data
});
リアルタイムで送信されるデータにアクセスするには、オブジェクトを処理する関数を実装する必要があります。この関数は次のようにする必要があります:

1 ReadableStream をプロミスとして受信します。

    データのすべてのチャンクが受信されるまで待ちます。
  1. チャンクを完全なデータセットにマージします。約束として完全なデータを返します。

Why the Streams API is a Game-Changer for Web Developers

ReadableStream の詳細

インターフェイス ReadableStream { 読み取り専用ロック: ブール値; cancel(reason?: any): Promise; getReader(オプション: { モード: "byob" }): ReadableStreamBYOBReader; getReader(): ReadableStreamDefaultReader; getReader(options?: ReadableStreamGetReaderOptions): ReadableStreamReader; PipeThrough( 変換: ReadableWritablePair, オプション?: StreamPipeOptions ): ReadableStream; パイプ先( 宛先: WritableStream、 オプション?: StreamPipeOptions ): Promise; tee(): [ReadableStream, ReadableStream]; }
interface ReadableStream {
  readonly locked: boolean;
  cancel(reason?: any): Promise;
  getReader(options: { mode: "byob" }): ReadableStreamBYOBReader;
  getReader(): ReadableStreamDefaultReader;
  getReader(options?: ReadableStreamGetReaderOptions): ReadableStreamReader;
  pipeThrough(
    transform: ReadableWritablePair,
    options?: StreamPipeOptions
  ): ReadableStream;
  pipeTo(
    destination: WritableStream,
    options?: StreamPipeOptions
  ): Promise;
  tee(): [ReadableStream, ReadableStream];
}
インターフェイス ReadableStreamDefaultReader extends ReadableStreamGenericReader { read(): Promise>; releaseLock(): 無効; }
fetch("url") .then((response) => {
// Note that there is a middle step before we receive the final data
// Let's see what we actually receive
console.log(response.body); return response.text(); }) .then((data) => { // Perform operations with the data
});
ストリームを操作するには、ReadableStreamDefaultReader を返す getReader() を使用します。

これは、特定のユーザー向けに PGN 形式 (テキストと考えてください) のゲーム用に Lichess.org の API にリクエストを行う例です。最終結果はテキストで表示される必要があります。


fetch("https://lichess.org/api/games/user/gg").then((response) => { console.log(応答); const readablestream = 応答.body; console.log(読み取り可能なストリーム); const リーダー = readablestream.getReader(); コンソール.ログ(リーダー); });
fetch("url") .then((response) => {
// Note that there is a middle step before we receive the final data
// Let's see what we actually receive
console.log(response.body); return response.text(); }) .then((data) => { // Perform operations with the data
});
出力:


ReadableStream { locked: false、state: 'readable'、supportsBYOB: true } ReadableStreamDefaultReader { stream: ReadableStream { locked: true、state: 'readable'、supportsBYOB: true }、readRequests: 0、close: Promise { } }
fetch("url") .then((response) => {
// Note that there is a middle step before we receive the final data
// Let's see what we actually receive
console.log(response.body); return response.text(); }) .then((data) => { // Perform operations with the data
});
ReadableStream.locked = true の場合、getReader() がエラーをスローするため、同時に複数のリーダーを持つことはできないことに注意してください。そのため、リーダーを変更したい場合は、まず ReadableStreamDefaultReader を使用してロックを解放する必要があります。リリースロック()


fetch("https://lichess.org/api/games/user/gg").then((response) => { const readablestream = 応答.body; console.log(読み取り可能なストリーム); const リーダー = readablestream.getReader(); コンソール.ログ(リーダー); 試す { Reader.releaseLock(); const Reader2 = readablestream.getReader(); // エラーはスローされません const Reader3 = readablestream.getReader(); // エラーがスローされます } キャッチ (e) { console.error(e.message); // 無効な状態: ReadableStream がロックされています } });
fetch("url") .then((response) => {
// Note that there is a middle step before we receive the final data
// Let's see what we actually receive
console.log(response.body); return response.text(); }) .then((data) => { // Perform operations with the data
});
今度は、2 つの変数を持つリーダー内で読み取り関数を使用します

    value: UintArray に現在のチャンクの内容があり、各 int を char に変換してマージするか、単に TextDecoder().decode() を使用することで文字列に変換できます。
let string = result.push( value.reduce((p, c) => { return p c.fromCharCode(); }, "") ); // または let string = new TextDecoder().decode(value); // どちらも Uint8Array を文字列に変換するという同じことを実現します
fetch("url") .then((response) => {
// Note that there is a middle step before we receive the final data
// Let's see what we actually receive
console.log(response.body); return response.text(); }) .then((data) => { // Perform operations with the data
});
完全なコード例

    ストリームの処理とチャンクの結合の完全な例を次に示します。
fetch("https://lichess.org/api/games/user/gg") .then((応答) => { return new Promise((解決、拒否) => { const readablestream = 応答.body; const リーダー = readablestream.getReader(); 結果 = []; とします。 Reader.read().then(function handlechunks({ 完了, 値 }) { if (完了) { 解決(結果); 戻る; } const pgn = new TextDecoder().decode(value); result.push(pgn); Reader.read().then(ハンドルチャンク); }); }); }) .then((結果) => { console.log(結果); });
interface ReadableStream {
  readonly locked: boolean;
  cancel(reason?: any): Promise;
  getReader(options: { mode: "byob" }): ReadableStreamBYOBReader;
  getReader(): ReadableStreamDefaultReader;
  getReader(options?: ReadableStreamGetReaderOptions): ReadableStreamReader;
  pipeThrough(
    transform: ReadableWritablePair,
    options?: StreamPipeOptions
  ): ReadableStream;
  pipeTo(
    destination: WritableStream,
    options?: StreamPipeOptions
  ): Promise;
  tee(): [ReadableStream, ReadableStream];
}
// console.log(値) Uint8Array(551) [ 91、69、118、101、110、116、32、34、82、97、116、101、 100、32、98、108、105、116、122、32、103、97、109、101、 34、93、10、91、83、105、116、101、32、34、104、116、 116、112、115、58、47、47、108、105、99、104、101、115、 115、46、111、114、103、47、90、122、78、66、90、119、 100、71、34、93、10、91、68、97、116、101、32、34、 50、48、50、48、46、48、49、46、49、48、34、93、 10、91、87、104、105、116、101、32、34、86、101、101、 118、101、101、50、 ... 451 件以上のアイテム ] // console.log(new TextDecoder().decode(value)) [イベント「格付け電撃戦」] [サイト「https://lichess.org/ZzNBZwdG」] [日付「2020.01.10」] [ホワイト「Veevee222」] [ブラック「gg」] [結果「0-1」] [UTC日付「2020.01.10」] [UTC時間「20:21:02」] [ホワイトエロ「1858」] [ブラックエロ「1863」] [WhiteRatingDiff "-6"] [BlackRatingDiff「35」] [バリエーション「スタンダード」] [タイムコントロール「180 0」] [エコ「C00」] [終了「正常」]
interface ReadableStream {
  readonly locked: boolean;
  cancel(reason?: any): Promise;
  getReader(options: { mode: "byob" }): ReadableStreamBYOBReader;
  getReader(): ReadableStreamDefaultReader;
  getReader(options?: ReadableStreamGetReaderOptions): ReadableStreamReader;
  pipeThrough(
    transform: ReadableWritablePair,
    options?: StreamPipeOptions
  ): ReadableStream;
  pipeTo(
    destination: WritableStream,
    options?: StreamPipeOptions
  ): Promise;
  tee(): [ReadableStream, ReadableStream];
}
1. e4 e6 2. d4 d6 3. c4 Nf6 4. Nc3 c5 5. f4 cxd4 6. Qxd4 Nc6 7. Qd1 b6 8. g3 Bb7 9. Bg2 Rc8 10. Nf3 Be7 11. O-O O-O 12. b3 Nb4 13. Bb2 a5 14.Re1 Qc7 15. a3 Na6 16. Rc1 Nc5 17. Qd4 Nxb3 18. Qd1 Nxc1 19. e5 0-1
fetch("url") .then((response) => {
// Note that there is a middle step before we receive the final data
// Let's see what we actually receive
console.log(response.body); return response.text(); }) .then((data) => { // Perform operations with the data
});
たとえばリンク

たとえば、完全なコード go

Why the Streams API is a Game-Changer for Web Developers

これで、ネットワーク経由で送信されるゲームの PGN に段階的にアクセスできるようになります。たとえば、Web サイト UI でロードされたゲームを使用している場合、ユーザーはすべてのゲームがロードされるまで空白の画面やロード画面の前で待つ必要がありません。代わりに、データを段階的に表示できるため、UX の観点からははるかに優れています。

たとえば、完全なコードはここにあります

リリースステートメント この記事は次の場所に転載されています: https://dev.to/anasmustafa123/why-the-streams-api-is-a-game-changer-for-web-developers-1030?1 侵害がある場合は、study_golang にご連絡ください。 @163.com 削除
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3