Node.js Highland.js中的嵌套流操作
我有一个来自Node.js Highland.js中的嵌套流操作,node.js,stream,highland.js,Node.js,Stream,Highland.js,我有一个来自readdirp模块的目录流 我想:- 在每个目录中使用正则表达式(例如,README.*)搜索文件 读取该文件中不以#开头的第一行 打印出每个目录以及目录中自述文件的第一个非标题行 我正在尝试使用流和 我一直在试图处理每个目录中的所有文件流 h = require 'highland' dirStream = readdirp root: root, depth: 0, entryType: 'directories' dirStream = h(dirStream)
readdirp
模块的目录流
我想:-
- 在每个目录中使用正则表达式(例如,
)搜索文件README.*
- 读取该文件中不以
开头的第一行#
- 打印出每个目录以及目录中自述文件的第一个非标题行
h = require 'highland'
dirStream = readdirp root: root, depth: 0, entryType: 'directories'
dirStream = h(dirStream)
.filter (entry) -> entry.stat.isDirectory()
.map (entry) ->
# Search all files in the directory for README.
fileStream = readdirp root: entry.fullPath, depth: 0, entryType: 'files', fileFilter: '!.DS_Store'
fileStream = h(fileStream).filter (entry) -> /README\..*/.test entry.name
fileStream.each (file) ->
readmeStream = fs.createReadStream file
_(readmeStream)
.split()
.takeUntil (line) -> not line.startsWith '#' and line isnt ''
.last(1)
.toArray (comment) ->
# TODO: How do I access `comment` asynchronously to include in the return value of the map?
return {name: entry.name, comment: comment}
<> P> >最好将高地流视为不可变的,如<代码>过滤器> /COD>和<代码> MAP>代码>返回依赖于旧流的新流,而不是修改旧流。 另外,Highland方法是懒惰的:当您现在绝对需要数据时,您应该只调用
每个
或到阵列
异步映射流的标准方法是flatMap
。它类似于map
,但是您赋予它的函数应该返回一个流。从flatMap
获得的流是所有返回流的串联。因为新流按顺序依赖于所有旧流,所以可以使用它对异步进程进行排序
我将您的示例修改为以下内容(澄清了一些变量名称):
让我们浏览一下代码中的类型。首先,请注意flatMap
具有类型(在Haskellish表示法中)流a→ (一)→ 溪流(b)→ 流b
,即,它接受一个包含a
类型某些内容的流,以及一个期望a
类型内容并返回包含b
s的流的函数,并返回一个包含b
s的流。将flatMap
实现为连接返回的集合是集合类型(如流和数组)的标准
h(readdirp root: root, depth: 0, entryType: 'directories')
假设它具有类型流目录
。filter
不会更改类型,因此flatMap
将是Stream目录→ (目录→ 溪流(b)→ 流b
。我们将看到函数返回的内容:
h(readdirp root: dir.fullPath, depth: 0, entryType: 'files', fileFilter: '!.DS_Store')
将其称为流文件
,因此第二个平面图
是流文件→ (档案→ 溪流(b)→ 流b
h(fs.createReadStream file.name)
这是一个流字符串
<代码>拆分,直到
和最后一次
都不改变,那么映射
做什么呢map
与flatMap
非常相似:它的类型是流a→ (一)→ (b)→ 流b
。在这种情况下,a
是String
,b
是一种对象类型{name:String,comment:String}
。然后map
返回该对象的流,这是整个flatMap
函数返回的。向上一步,第二个flatMap
中的b
是对象,因此第一个flatMap
函数也返回对象流,因此整个流是流{name:String,comment:String}
注意,由于Highland的懒惰,这实际上不会启动任何流或处理。您需要使用each
或toArray
来引起thunk
并启动管道。在每个中,将使用对象调用回调。根据您希望对注释执行的操作,最好再执行一些flatMap
(例如,如果您正在将注释写入文件)
嗯,我不是有意写一篇文章的。希望这有帮助。 < P> >最好将高地流视为不可变的,操作如<代码>过滤器< /COD>和<代码> MAP>代码>返回依赖于旧流的新流,而不是对旧流的修改。 另外,Highland方法是懒惰的:当您现在绝对需要数据时,您应该只调用
每个
或到阵列
异步映射流的标准方法是flatMap
。它类似于map
,但是您赋予它的函数应该返回一个流。从flatMap
获得的流是所有返回流的串联。因为新流按顺序依赖于所有旧流,所以可以使用它对异步进程进行排序
我将您的示例修改为以下内容(澄清了一些变量名称):
让我们浏览一下代码中的类型。首先,请注意flatMap
具有类型(在Haskellish表示法中)流a→ (一)→ 溪流(b)→ 流b
,即,它接受一个包含a
类型某些内容的流,以及一个期望a
类型内容并返回包含b
s的流的函数,并返回一个包含b
s的流。将flatMap
实现为连接返回的集合是集合类型(如流和数组)的标准
h(readdirp root: root, depth: 0, entryType: 'directories')
假设它具有类型流目录
。filter
不会更改类型,因此flatMap
将是Stream目录→ (目录→ 溪流(b)→ 流b
。我们将看到函数返回的内容:
h(readdirp root: dir.fullPath, depth: 0, entryType: 'files', fileFilter: '!.DS_Store')
将其称为流文件
,因此第二个平面图
是流文件→ (档案→ 溪流(b)→ 流b
h(fs.createReadStream file.name)
这是一个流字符串
<代码>拆分,直到
和最后一次
都不改变,那么映射
做什么呢map
与flatMap
非常相似:它的类型是流a→ (一)→ (b)→ 流b
。在这种情况下,a
是String
,b
是一种对象类型{name:String,comment:String}
。然后map
返回该对象的流,这是整个flatMap
函数返回的。向上,第二个flatMap
中的b
是对象,因此f