Node.js 流星观测阵列服务器端
我有一个递归函数,它在服务器端异步构建一棵树,我希望“观察”它,并在每次发生更改时让Meteor中的调用方法重新运行 我制作了一个简化的示例,该示例使用递归readdir调用构建一棵树(在实际应用程序中,每个节点可能需要几分钟的计算,其结果取决于已探索的节点) 在server/methods.js中Node.js 流星观测阵列服务器端,node.js,asynchronous,recursion,meteor,Node.js,Asynchronous,Recursion,Meteor,我有一个递归函数,它在服务器端异步构建一棵树,我希望“观察”它,并在每次发生更改时让Meteor中的调用方法重新运行 我制作了一个简化的示例,该示例使用递归readdir调用构建一棵树(在实际应用程序中,每个节点可能需要几分钟的计算,其结果取决于已探索的节点) 在server/methods.js中 var fs = Meteor.npmRequire('fs') var path = Meteor.npmRequire('path') var tree = function (dir, r)
var fs = Meteor.npmRequire('fs')
var path = Meteor.npmRequire('path')
var tree = function (dir, r) {
try
{
fs.readdir (dir, function (error, files) {
if (files && files.length)
for (var i = 0; i < files.length; i++)
{
r[i] = { name : files[i], children : [] }
tree(path.resolve(dir, files[i]), r[i].children)
}
})
} catch (e) { console.log("exception", e)}
}
Meteor.methods({
'build_tree' : function () {
var r = []
tree("/tmp/", r)
return r // Wrong !
}
})
我已经在基于的代码的其他部分使用了futures
但在这种情况下,我不知何故迷失了方向
- 服务器端代码的递归性质
- 我希望客户端在每次更新服务器端数据结构时自动更新
我想到的唯一解决办法是逐步将异步结果插入到“平面”Mongo集合中,并在客户端将其作为树进行反应性重建。这确实非常复杂。首先,当树代码异步运行时,您需要提供一个成功回调/解析一个承诺/返回一个未来或其他东西,以便您可以控制Meteor方法何时返回。然后,您需要使用Futures来延迟方法的返回,直到您得到结果为止 但即使这样,我也不明白服务器应该如何知道发生了变化 我想到的唯一解决办法是逐步将异步结果插入到“平面”Mongo集合中,并在客户端以树的形式反应性地重建它
这实际上是一个简单可行的解决方案。我通过
- 计算异步计算启动的次数 还是完成了
- 只有当这些数字相等时,才能解决未来问题
- 每次异步计算结束时重新启动函数 (以防它返回以启动更多异步计算或解决未来问题)
Future = Meteor.npmRequire('fibers/future')
FS = Meteor.npmRequire('fs')
Path = Meteor.npmRequire('path')
const all_files = []
const future = new Future()
const to_process = [dir]
let started = 0
let ended = 0
const tree = function () {
while (to_process.length) {
let dir = to_process.pop()
started++
FS.readdir (dir, function (error, files) {
if (error) {
if (error.code == 'ENOTDIR') all_files.push(dir)
}
else if (files && files.length)
{
for (let i = 0, leni = files.length; i < leni; i++)
{
let f = Path.resolve(dir, files[i])
to_process.push(f)
}
}
ended++
tree()
})
}
if (!to_process.length && started == ended)
future['return']()
}
tree()
future.wait()
Future=Meteor.npmRequire(“光纤/未来”)
FS=流星npmRequire('FS'))
路径=Meteor.npmRequire('路径')
const all_文件=[]
const future=新未来()
const to_进程=[dir]
让我们开始=0
设结束=0
常量树=函数(){
while(to_进程长度){
let dir=to_process.pop()
开始++
FS.readdir(dir,函数(错误,文件){
如果(错误){
如果(error.code=='ENOTDIR')所有_文件.push(dir)
}
else if(files&&files.length)
{
for(设i=0,leni=files.length;i
它没有“渐进式更新”的感觉,因为所有的计算都在等待最终的未来['return']()
,但是代码更简单,而且是自包含的
Future = Meteor.npmRequire('fibers/future')
FS = Meteor.npmRequire('fs')
Path = Meteor.npmRequire('path')
const all_files = []
const future = new Future()
const to_process = [dir]
let started = 0
let ended = 0
const tree = function () {
while (to_process.length) {
let dir = to_process.pop()
started++
FS.readdir (dir, function (error, files) {
if (error) {
if (error.code == 'ENOTDIR') all_files.push(dir)
}
else if (files && files.length)
{
for (let i = 0, leni = files.length; i < leni; i++)
{
let f = Path.resolve(dir, files[i])
to_process.push(f)
}
}
ended++
tree()
})
}
if (!to_process.length && started == ended)
future['return']()
}
tree()
future.wait()