流星观察数组服务器端

9
我有一个递归函数,在服务器端异步构建一棵树,我希望可以“观察”它,并且每当有变化时都能让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/client.js文件中

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

在代码的其他部分中,我已经使用了基于 https://www.discovermeteor.com/patterns/5828399 的期货。但在这种情况下,由于以下原因,我有些困惑:

  • 服务器端代码的递归性质
  • 希望每次更新服务器端数据结构时,客户端自动更新

我能想到的唯一解决方法是将异步结果逐步插入“平坦”的Mongo集合,并在客户端重新构建树形结构以实现反应式重建。

2个回答

10
我通过以下方式实现了这个功能:
  • 计算异步计算启动或完成的次数
  • 只有当这些数字相等时才解决future
  • 每当一个异步计算结束时重新启动函数(以防它返回以启动更多异步计算或解决future)

[用于关闭列表标记或代码以确保格式正确]

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['return'](),但代码更简单、自包含。


5

这将会非常复杂。首先,由于您的树形代码是异步运行的,您需要提供一个成功回调/解析承诺/返回未来或其他内容,以便您可以控制Meteor方法何时返回。然后,您需要使用Futures延迟方法的返回,直到您获得结果。

但即使如此,我也不知道服务器应该如何知道发生了什么变化。

我所能想到的唯一解决方法是逐步将异步结果插入到“平坦”的Mongo集合中,并在客户端上以响应式方式重新构建它。

这实际上是一个可行且简单的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接