meteor观察阵列服务器端

时间:2015-04-17 13:30:27

标签: 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) {
  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 !
  }
})
客户端/ client.js中的

Meteor.call('build_tree', function (error, result) {
   console.log(error, result)
}

我已经在基于https://www.discovermeteor.com/patterns/5828399的代码的其他部分使用了期货。

但在这种情况下,由于

,我不知何故失去了
  • 服务器端代码的递归特性
  • 我希望客户端每次更新服务器端数据结构时自动更新

我想到的唯一解决方法是逐步将异步结果插入“扁平”Mongo集合中,并在客户端以树的形式反复重建它。

2 个答案:

答案 0 :(得分:10)

我设法通过

来做到这一点
  • 计算异步计算开始的次数
  • 只有当这些数字相等时才能解决未来
  • 每次异步计算结束时重新启动该函数 (如果它返回启动更多异步计算或解决未来)

[关闭列表标记的行或代码没有正确格式化]

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

它没有&#34;渐进式更新&#34;感觉你通过更新数据库并让反应性来管理它,因为所有的计算都在等待最后的Future['return']()但代码更简单和自包含。

答案 1 :(得分:5)

那确实非常复杂。首先,当您的树代码运行异步时,您需要提供成功回调/解决承诺/返回未来或其他内容,以便您可以控制Meteor方法何时返回。然后你需要使用Futures来推迟返回你得到结果的方法。

但即便如此,我也看不到服务器应该知道某些事情发生了变化。

  

我想到的唯一解决方法是逐步将异步结果插入“扁平”Mongo集合中,并在客户端以树的形式反复重建它。

这实际上是一个可行的直接解决方案。