Node.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)

我有一个递归函数,它在服务器端异步构建一棵树,我希望“观察”它,并在每次发生更改时让Meteor中的调用方法重新运行

我制作了一个简化的示例,该示例使用递归readdir调用构建一棵树(在实际应用程序中,每个节点可能需要几分钟的计算,其结果取决于已探索的节点)

在server/methods.js中

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()