2013-02-10 88 views
1

在客戶端插入(更新,刪除...)集合時,本地觀察者將同步觸發,即在本地模擬插入效果時觸發。這意味着後面的代碼可以依賴於插入的所有副作用而不存在競態條件。爲什麼observe()不能在服務器上同步執行?

服務器上的行爲似乎有所不同:觀察者似乎異步觸發,插入回調可能在觀察者執行之前返回。這使得正確同步代碼變得更加困難:我無法找到一個可靠的方法來判斷插入的所有副作用何時發生。除了在客戶端上,這會在插入操作後直接依賴副作用時創建爭用條件,並且在客戶端和服務器之間共享代碼變得更加困難。

這是預期的行爲?在服務器端有沒有一個很好的解決方法來告訴所有觀察者何時執行? (我的用例:我有一個「命令」表,我需要撤消/重做。插入一個新命令將觸發對本地非同步集合的更改,即命令從觀察者內部執行。後續命令要求對本地集合的更改完成,否則將失敗。)

+0

這是延遲補償投入行動。爲了避免它,你可以使用'Meteor.call'和'Meteor.methods'。如果客戶端/服務器由於某種原因未同步,則該操作在客戶端反轉,並且在回調中引發錯誤。我也問過類似的問題http://stackoverflow.com/questions/14800971/meteor-latency-compensation-and-hinting-completion-commit-to-the-user – Akshat 2013-02-10 22:36:48

+0

@Akshat:這個問題不是關於延遲補償或同步客戶端和服務器。它是關於node.js中的異步代碼執行(僅限於服務器)與瀏覽器中的同步代碼執行(僅限客戶端)。 Meteor通常使用光纖來「模擬」服務器上的同步行爲。但在這裏觀察員看來並不是這樣。我懷疑這是我忽略的一個很好的理由。 – jerico 2013-02-11 00:09:41

+0

是的,我看到你已經編輯了這個問題來澄清這個問題,你能提供你用來顯示這種情況的代碼嗎? – Akshat 2013-02-11 00:11:55

回答

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

這是一個未記錄的功能,而不是保證從長遠來看能夠工作。因此,如果核心團隊想要描述官方解決方案,我的問題仍然存在。

相關問題