1

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

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

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

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

4

1 回答 1

1

我在流星谈话群里找到了答案。相应的代码注释可以在这里找到:

// 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.
...

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

于 2013-02-11T00:39:20.810 回答