我尝试使用node.js
实现读取FileSystem目录树的列表结构DIR /文件结构:
DIR1
DIR2R
file1
file2
file3
…
- >列表结构:
("DIR1" ("DIR2" "file1" "file2" "file3" …))
DIR() //looks like a C function
file //looks like an Atom value
所以,例如,给定的UNIX根目录DIR:
root bin cd
ls
lib file1
file2
opt
usr file3
file4
相当于一个列表:
("root" ("bin" ("cd" "ls")
"lib" ("file1" "file2")
"opt" ()
"usr" ("file3")
"file4"
)
)
话虽如此,我想用一些懒惰的异步序列(流/无限列表?)来实现这段代码。
node.js fs.readdir recursive directory search 是一个很好的参考。
node.js有许多优秀的库,例如file.walk等,但这是一个非常有趣的主题,事实上,许多代码示例都存在。
换句话说,一个好学科学习懒惰异步序列的基本概念(流/无限列表?),而且代码可以是一个很好的库,我想从头开始实现。
substack/stream-handbook介绍了如何编写node.js的基础知识 程序streams。 真正优秀的文章。
所以,这是我对这个主题的想法 - 递归目录树处理:
此主题涉及递归搜索,有两种方法:异步和同步,由于各种原因,我选择 async 方法。
搜索结果相当于列表结构,其中功能编程范例很重要(Lisp / Scheme)。
对于JavaScript函数式编程,有一些库,例如 underscore.js ,最近有 lazy.js ,但有一个重要区别:懒惰评估(也称为延迟执行)似乎胜过underscore.js 。
lazy.js也包装了Node.js中的流处理。我还发现stream.js说:无数个元素。他们的力量来自懒惰的评价,简单来说就意味着他们可以包含无限的物品。。
流数据(无限列表)实现反应函数编程(FRP)范例。 lazy.js实际上演示了一个鼠标事件FRP实现。 RxJS是一个FRP库:JavaScript的 RxJS或Reactive Extensions 是一个用于转换,编写和查询数据流的库< /强>
async 此主题的方法 FRP 主题。
因此,延迟评估是更快的List处理功能编程的核心因素,并将列表扩展为无限列表(流),它将async /事件集成到Stream数据源以进行处理编程范例(FunctionalReactiveProgramming)。
node-lazy简介明确指出:当您需要处理列表等事件流时,Lazy非常方便。目前最好的用例是从异步函数返回一个惰性列表,并通过事件将数据输入其中。在异步编程中,您不能只返回常规列表,因为您还没有数据。到目前为止,通常的解决方案是提供一个在数据可用时调用的回调。但是这样做会失去链接函数和创建管道的能力,导致不那么好的接口。 (请参阅下面的第二个示例,了解它如何改进我的某个模块中的界面。)
最后,这是我关于这个主题的问题 - 递归目录树处理:
是否有任何示例代码仅以延迟评估或FRP方式实现此主题?
我知道lazy.js,stream.js或linq.js基于延迟评估,但是其中任何一个都不能将node.js fs.readdir定义为异步处理(FRP)的流数据< / strong>即可。根据{{3}},它还没有实现,对吗?
http://danieltao.com/lazy.js/docs/AsyncSequence.html可能可以,但我不知道如何。
有什么想法吗?
答案 0 :(得分:0)
这是基于https://gist.github.com/edygar/ee0945a73c79182367df
的开始给定一个目录,它会生成一个子目录列表。
(CoffeeScript的)
Rx = require "rx"
fs = require "fs"
readdir = Rx.Observable.fromNodeCallback fs.readdir
stat = Rx.Observable.fromNodeCallback (pathName, cb) ->
fs.stat pathName, (err, stats) ->
stats.pathName = pathName
cb err, stats
dirObservable = (dirPath) ->
readdir dirPath
.flatMap (items) -> Rx.Observable.from items
.flatMap (item) -> stat item
.filter (stats) -> stats.isDirectory()
.map (stats) -> stats.pathName
module.exports = dirObservable
if not module.parent
path = require "path"
dirobs = dirObservable path.resolve __dirname, ".."
dirobs.subscribe (data) -> console.log data