ホームページ > 記事 > ウェブフロントエンド > Node.js_node.js の Stream モジュールの Readable オブジェクトの簡単な分析
私は、nodejs について話すことにいつも気が進まなかった。初めて見たときから、そのデザインが本当に気持ち悪いと思ったからである。しかし、それは仕方がありません。ストリーム仕様はまだ普及していませんし、実際に実装するにはnodejsストリームに依存するものがたくさんあるので、鼻をつまんで引っ張るしかありませんこれは臭くて難しいです。
Nodejsにはstreamというモジュールが付属しており、これを導入することでストリームオブジェクトのコンストラクタ一式を取得できます。ここでは、最も単純な stream.Readable についてのみ説明します。
実際、nodejs を使用したことのあるほぼ全員が Readable インスタンスに触れたことがあるものの、あまり注目していません。非常に典型的な例では、http モジュールでは、各リクエストを処理するときに req オブジェクトと res オブジェクトが存在します。Req は実際には Readable オブジェクトです。このリクエストでは、HTTP リクエストのエンティティ部分をストリームの形式で読み取ることができます。
そこで問題は、なぜここで http モジュールがストリーミング方式で設計されているのかということです。あるいは、この質問を別の次元から尋ねると、「nodejs はどのようにして POST リクエストのコンテンツを取得しますか?」ということになります。検索エンジンの使用方法を知っている学生であれば、そのような答えを簡単に見つけることができます。つまり、データ イベントを聞いてデータを収集し、収集したデータを最終イベントでマージします。はい、これがこの問題の解決策です。しかし、なぜこのように設計されているのでしょうか? PHP のように POST コンテンツを直接取得できたらどんなに素晴らしいでしょうか?実際、この設計は有益です。受信したデータが不正な場合は、すぐに検出して対応し、接続を切断できます。これにより、不必要な伝送コストを回避できます。たとえば、画像をアップロードするときに、ユーザーが誤って大きな実行可能ファイルを選択してしまう可能性があります。ファイルが完全にアップロードされるまで待つ必要はありません。ファイルが画像であるかどうかを判断するために必要なのは、ファイル ヘッダーの数バイトだけです。 。ここでストリーム設計を使用すると、最初に最初の数バイトを読み出して使用できます。
上記のデータイベントと終了イベントはいずれも Readable イベントであり、それぞれデータの受信とデータ受信の完了を示します。つまり、実際のところ、Readable の使い方はすでにわかっていますが、多くの人はそれが Readable オブジェクトであることを知りません。
ただし、上記の 2 つのイベントは、Readable のコンシューマー向けのイベントのみです。 Readable がこれらのイベントをトリガーできるように、データの一部を Readable オブジェクトに内部的にプッシュするにはどうすればよいでしょうか?次にプッシュ方式です。これは、増加する数値をストリーミングする Readable オブジェクトを作成する例です (ここでは babel-node が使用されます)
import stream from 'stream'; var r = new stream.Readable; r.on('data', data => { console.log(data + ''); }); r.on('end', data => { console.log('end'); }); r._read = () => { // console.log('before read'); }; void function callee(i) { if(i < 10) { r.push(i + ''); // 只能传入字符串或 Buffre 对象 } else { r.push(null); // 当输入一个 null 时表示流传输完成,触发 end 事件 } setTimeout(callee, 500, i + 1); }(0);
上記のコードを注意深く見てみると、このコードは _read メソッドをオーバーライドしていることがわかります。これは一体何でしょうか。実際、これは落とし穴だとも思いますが、このプライベートな命名スタイルについては、なぜこのメソッドをオーバーライドする必要があるのでしょうか。このメソッドがオーバーライドされていない場合、プッシュを呼び出すときに例外がスローされます:
Error: not implemented at Readable._read (_stream_readable.js:464:22) at Readable.read (_stream_readable.js:341:10)
以上が Readable オブジェクトの基本的な使い方です。ただし、さらに落とし穴があります。この記事は、データを出力できる Readable オブジェクトの作成方法を誰もが学べるようにするための最も簡単な紹介にすぎません。読み取りなどの基本的なメソッドについては、いずれにしても非科学的な設計の 1 つです。