2014-01-08 38 views
1

我有一個jQuery小部件,其中包含變量this.options._offset和函數_drawPlot()。當用戶拖放&時,會執行一個函數_drawPlot(),並在最後更新this.options._offsetjQuery小部件:全局變量不一致

現在的問題是,用戶可能拖得太快,導致變量_offset不一致。例如,兩個拖&拖放操作A和B,也許執行順序:

A: plotting 
A: update offset 
B: plotting 
B: update offset 

或者:

A: plotting 
B: plotting 
A: update offset 
B: update offset 

offset不是第二種情況下是正確的。我認爲JS是單線程的,從來沒有預料到會發生這種情況。這就像操作系統中的信號量。或者是因爲console.log在欺騙我?但無論如何,使用_offset的函數_drawPlot()的行爲錯誤。

我知道我可以節流操作,但即使在節流後,如果_drawPlot()運行很長時間,問題仍然存在。

有沒有辦法控制這個?

+0

'_offset'是由'_drawPlot()'函數直接更新還是由一個不同的處理程序綁定到某種地方觸發的「完成繪圖」事件?一些代碼可能會有所幫助 – matpop

+5

是的,請添加一些代碼。 JavaScript確實是單線程的,但它具有異步執行代碼的特點。解決方案應該在代碼中的某個地方,根據迄今爲止發佈的內容,這裏沒有任何答案。 –

+2

爲了獲得更多的幫助,你總是可以發佈一個jsfiddle.net/ –

回答

3

在某些情況下,瀏覽器中的JavaScript將表現異步 - 例如,想象通過網絡加載資源。實際上,這是其中一件事,因爲像一流的功能等功能相當不錯。

簡短的答案是 - 不使用全局變量。使用對象和事件來隔離這些行爲,以使它不會影響它們發生的順序。例如,在兩個不同的對象上有一個偏移屬性,而不是每個事件都重複使用的屬性。

+1

好點,但有時(我敢打賭,情況就是這樣)執行順序非常重要,所以全局變量(是它們的整數或阻塞隊列,或多或少直接可供程序員訪問)可能變得必要,因爲你無法在本地變量上同步。 – matpop

+0

是的,我同意 - 如果dragStart事件在dragEnd事件之前觸發,那麼無論如何訂單都會被搞亂。在這種情況下,我會研究爲什麼這些事件發生了奇怪的事情(可能是鼠標離開應該捕捉dragEnd事件的dom元素)。 –

3

這是我遇到的一個問題,在使用類似extjs或jQuery的庫時,經常出現在Javascript中。

我到目前爲止唯一可行的解​​決方案是通過鎖來處理變量設置。 Sux製作大片時間,但它是唯一安全的處理方式。像

if (!this.lock) { 
    this.lock = true; 
    //do the actual function call 
} 

並在第二個事件的完成我把解鎖呃,每次工作與代碼運行同步。

這是從這種事件驅動系統的概念中得出的缺陷。如果您需要在事件驅動的環境中同步行爲,則必須將鎖定到位。