为什么observe()不能在服务器上同步执行?

时间:2013-02-10 21:23:56

标签: meteor

当插入(更新,删除......)到客户端上的集合时,本地观察者将同步触发,即在本地模拟插入的效果时。这意味着后续代码可以依赖于插入的所有副作用而没有竞争条件。

服务器上的行为似乎有所不同:观察者似乎异步触发,插入回调可能会在观察者执行之前返回。这使得正确同步代码变得更加困难:我无法找到一种可靠的方法来判断插入的所有副作用何时发生。除了客户端之外,在插入操作之后直接依赖副作用时会产生竞争条件,并且在客户端和服务器之间共享代码变得更加困难。

这是预期的行为吗?服务器端是否有一个好的解决方法来告诉所有观察者何时执行?

(我的用例:我有一个“命令”表,我需要撤消/重做。插入一个新命令将触发对本地非同步集合的更改,即命令正在观察者中执行。命令要求对本地集合的更改完成,否则它们将失败。)

1 个答案:

答案 0 :(得分:1)

我在meteor-talk group找到了答案。可以找到相应的代码注释here

// After making a write (with insert, update, remove), observers are
// notified asynchronously. If you want to receive a callback once all
// of the observer notifications have landed for your write, do the
// writes inside a write fence (set Meteor._CurrentWriteFence to a new
// _WriteFence, and then set a callback on the write fence.)

万一你想知道在实践中看起来如何 - 这就是我所做的(在coffeescript中):

Future = __meteor_bootstrap__.require('fibers/future')
...
future = new Future
fence = new Meteor._WriteFence
fence.onAllCommitted ->
  fence.retire()
  future.ret()
result = Meteor._CurrentWriteFence.withValue fence, ->
  # do something that triggers observers
  ...
  return result
fence.arm()
future.wait() # This will return only /after/ all observers fired.
...

这是一个未记录的功能,不能保证长期工作。因此,如果核心团队想要描述正式的解决方法,我的问题仍然存在。