Highland ストリームは不変であり、古いストリームを変更するのではなく、古いストリームに依存する新しいストリームを返すfilter
などの操作を検討するのが最善です。map
また、ハイランド メソッドは怠惰です。今すぐデータが絶対に必要な場合にのみeach
orを呼び出す必要があります。toArray
ストリームを非同期的にマッピングする標準的な方法はflatMap
. のようなものmap
ですが、指定した関数はストリームを返す必要があります。取得するストリームflatMap
は、返されたすべてのストリームを連結したものです。新しいストリームはすべての古いストリームに順番に依存するため、非同期プロセスの順序付けに使用できます。
あなたの例を次のように変更します(いくつかの変数名を明確にしました):
h = require 'highland'
readmeStream = h(readdirp root: root, depth: 0, entryType: 'directories')
.filter (dir) -> dir.stat.isDirectory()
.flatMap (dir) ->
# Search all files in the directory for README.
h(readdirp root: dir.fullPath, depth: 0, entryType: 'files', fileFilter: '!.DS_Store')
.filter (file) -> /README\..*/.test file.name
.flatMap (file) ->
h(fs.createReadStream file.name)
.split()
.takeUntil (line) -> not line.startsWith '#' and line isnt ''
.last(1)
.map (comment) -> {name: file.name, comment}
このコードの型を見てみましょう。flatMap
まず、が type (ハスケル記法) を持っていることに注意してくださいStream a → (a → Stream b) → Stream b
。つまり、 type のものをいくつか含むストリームと、 type のa
ものを期待し、 sa
を含むストリームをb
返す関数を取り、s を含むストリームを返しますb
。コレクション型 (ストリームや配列など)flatMap
は、返されたコレクションを連結して実装するのが標準です。
h(readdirp root: root, depth: 0, entryType: 'directories')
これに type があるとしましょうStream Directory
。はfilter
型を変更しないため、flatMap
は になりますStream Directory → (Directory → Stream b) → Stream b
。関数が何を返すか見てみましょう。
h(readdirp root: dir.fullPath, depth: 0, entryType: 'files', fileFilter: '!.DS_Store')
これを a と呼ぶStream File
ので、2 番目flatMap
はStream File → (File → Stream b) → Stream b
です。
h(fs.createReadStream file.name)
これはStream String
. split
、takeUntil
そしてlast
それを変更しないでください。では、 は何をしmap
ますか? map
は と非常によく似ていflatMap
ます: そのタイプはStream a → (a → b) → Stream b
です。この場合、 a
isString
とb
is は object type{name : String, comment : String}
です。次に、そのオブジェクトのストリームを返します。これは、関数map
全体が返すものです。flatMap
ステップアップb
し、2 番目flatMap
はオブジェクトであるため、最初flatMap
の の関数もオブジェクトのストリームを返すため、ストリーム全体はStream {name : String, comment : String}
.
Highland の遅延により、実際にはストリーミングや処理が開始されないことに注意してください。each
またはtoArray
を使用thunk
してパイプラインを開始する必要があります。ではeach
、オブジェクトでコールバックが呼び出されます。コメントで何をしたいかによっては、flatMap
もっと多くするのが最善かもしれません (たとえば、コメントをファイルに書き込んでいる場合)。
まあ、エッセイを書くつもりはありませんでした。お役に立てれば。