第6章 ストリーム
この作品はAIを使って翻訳されている。ご意見、ご感想をお待ちしている:translation-feedback@oreilly.com
Nodeストリームは理解しにくく、扱いにくいという評判がある。Nodeの初期はそうだったかもしれないが、状況は変わった。現在では、Nodeでストリームを作成したり消費したりするのは比較的簡単だ。ネイティブJavaScriptの非同期イテレータやジェネレータを使ってNodeストリームを扱うこともできる。
この章では、ストリームの概念、ストリームが必要な理由、そして、Nodeプロセスで利用可能なメモリを圧迫することなく大量のデータを効率的に処理するためのストリームの作成、使用、組み合わせ方について説明する。
ストリームの紹介
インターネットからファイルをダウンロードしたり、番組を見たり、曲を聴いたりするとき、あなたはストリームを使っている。コンテンツは、一度に一つの塊としてストリーミングされる。
ストリームは基本的に、配列や文字列と同じようなデータの集まりだが、データをメモリ空間にストアする代わりに、ストリームは時間をかけてデータを処理する。ストリームを使えば、限られたメモリースペースで大量のデータを処理することができる。
流れのアナロジーは、私たちの生活のいたるところにある。シンクが汚れた食器でいっぱいになったとき、食器洗い機に入れれば、食器を一度に処理することができる。食洗機が使えない場合は、ストリームという概念を採用し、シンクを一皿ずつ片付ける必要がある。1つの食器を洗って、すすいで、次の食器に移る。
これは、洗う食器の数が少ない場合に最適だ。洗う食器の数が多く、手伝ってくれる人がいる場合は、2つの水流を使うことができる!一人が洗い、もう一人がすすぐ。一人一人が異なるタスクを処理するが、あるプロセス(すすぎ)の入力は、別のプロセス(こすり洗い)の出力に依存する。そこから乾燥や積み重ねなど、さらに流れを追加することができる。こうして複数の流れを組み合わせることで、作業を効率化することができるのだ。
、あるストリームの出力を別のストリームの入力として使うことをパイピングという。これはUnix OSで使われる用語と同じで、パイプはあるプロセスから別のプロセスへデータを転送するために使われる。
Linuxでパイプを使う例を挙げよう。ある大きなプロジェクトで、require という単語がどのファイルに出現するかをカウントすることになったとする。Linuxには、ファイルのパターンを発見するgrep コマンドと、行、単語、文字をカウントするwc コマンドがある。grep コマンドの出力を使い、wc コマンドの入力としてパイプすることができる:
$ grep -wR require * | wc -l
Linuxのパイプは、小さなコマンドから強力なコマンドを構成することを可能にし、ストリーム同士をパイプでつなぐことができるため、合成可能な力をも与えてくれる。
Nodeにgrep へのストリームとwc へのストリームがあったとすると、 このように組み合わせることができる:
constgrep=...// A stream for the grep outputconstwc=...// A stream for the wc inputgrep.pipe(wc)
あるいは、食器洗いの例えを擬似コードに置き換えることもできる:
constscrub=...// An output ...