简体   繁体   English

流星观察阵列服务器端

[英]meteor observe array server side

I have a recursive function that builds asynchronously a tree on the server side and I would like to 'observe' it and have the calling method in Meteor rerun every time there is a change. 我有一个递归函数,它在服务器端异步构建一棵树,我想“观察”它,并在每次更改时重新运行Meteor中的调用方法。

I have made a simplified example that builds a tree with a recursive readdir call (in the real application there is a computation that may take several minutes per node and its results depend on the nodes already explored) 我做了一个简化的示例,该示例使用递归readdir调用构建树(在实际应用程序中,每个节点可能需要花费几分钟的时间进行计算,其结果取决于已经探索的节点)

in server/methods.js 在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 !
  }
})

in client/client.js 在client / client.js中

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

I have already used futures in other parts of the code based on https://www.discovermeteor.com/patterns/5828399 . 我已经在基于https://www.discovermeteor.com/patterns/5828399的代码的其他部分中使用了Future

But in this case I am somehow lost due to 但是在这种情况下,我由于某种原因迷路了

  • the recursive nature of the server-side code 服务器端代码的递归性质
  • the fact I want the client-side to update automatically every time the server-side data structure is updated 我希望客户端在每次更​​新服务器端数据结构时自动更新的事实

The only workaround that comes to my mind is to insert progressively the asynchronous results in a 'flat' Mongo collection and reactively rebuild it as a tree on the client side. 我想到的唯一解决方法是,将异步结果逐步插入“平坦的” Mongo集合中,然后在客户端将其作为树重建。

I managed to do this by 我设法做到了

  • counting the number of times an asynchronous computation was started or finished 计算异步计算开始或完成的次数
  • resolving the future only when those numbers are equal 只有当这些数字相等时才解决未来
  • relaunching the function every time an asynchronous computation ends (in case it returned to launch more asynchronous computations or resolve the future) 每次异步计算结束时重新启动该函数(以防它返回以启动更多异步计算或解决未来问题)

[line to close list markup or code doesn't format properly] [关闭列表标记的行或代码格式不正确]

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

It doesn't have the "progressive update" feeling that you get by updating the database and letting the reactivity manage it since all computations are waiting for that final Future['return']() but the code is simpler and self-contained. 它不具有通过更新数据库并让反应性对其进行管理而获得的“渐进式更新”感觉,因为所有计算都在等待最终的Future['return']()但是代码更简单且自成体系。

That would be indeed very complicated. 那确实是非常复杂的。 First of all, as your tree code runs async you need to either provide a success callback/resolve a promise/return a future or something else, so that you can control when the Meteor method returns. 首先,当树代码异步运行时,您需要提供成功的回调/解决承诺/返回未来或其他方式,以便您可以控制Meteor方法何时返回。 Then you need to use Futures to defer the return of the method util you have your result. 然后,您需要使用Futures推迟您获得结果的方法的返回。

But even then I don't see how the server is supposed to know that something has changed. 但是即使那样,我仍然看不到服务器应该如何知道某些更改。

The only workaround that comes to my mind is to insert progressively the asynchronous results in a 'flat' Mongo collection and reactively rebuild it as a tree on the client side. 我想到的唯一解决方法是,将异步结果逐步插入“平坦的” Mongo集合中,然后在客户端将其作为树重建。

This is actually a workable straightforward solution. 这实际上是一个可行的简单解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM