2009-02-17 113 views
43

在Javascript中是否存在原子測試和設置,信號量或鎖定這樣的事情?Javascript信號量/測試和設置/鎖?

我有通過自定義協議的JavaScript調用異步後臺進程(後臺進程字面上運行在單獨的進程,無關的瀏覽器)。我相信我正處於競賽狀態;後臺進程在我的測試和我的設置之間返回,在JavaScript端搞砸了。我需要一個測試和設置操作來使它成爲一個真正的信號量。

下面是試圖檢測後臺進程並預約的JavaScript代碼:

Call = function() { 

var isRunning = true, 
    queue = []; 

return { 
    // myPublicProperty: "something", 

    call: function (method) { 
      if (isRunning) { 
       console.log("Busy, pushing " + method); 
       queue.push(method); 
      } else { 
       isRunning = true; 
       objccall(method); 
      } 
     }, 

     done: function() { 
      isRunning = false; 
      if (queue.length > 0) { 
       Call.call(queue.shift()); 
      } 
     } 
    }; 
}(); 

呼叫是實現排隊一個單;任何想調用外部進程的人都會調用call.call(「something」)。

任何想法?

+0

您可能想詳細說明「流程」更詳細。這是服務器端的JavaScript? – 2009-02-17 01:13:25

+2

Javascript代碼總是原子的,所以不需要鎖定或任何東西。請參閱[爲什麼我們沒有JavaScript中的併發控制工具?](http://uzairfarooq.github.io/why-no-concurrency-control-tool-in-javascript/)。 – 2015-07-17 17:13:06

回答

2

也許你可以如果使用這樣的框架實現一個基本的整數信號量,只需添加變量到DOM和鎖定/解鎖,並確保你的函數繼續檢查它,否則超時他們=)

作爲Mootools,您可以嘗試使用onComplete等事件來處理應用程序的流程。

18

JavaScript沒有鎖定語義,因爲JS不是多線程語言。多個線程只能在完全不同的環境中同時運行 - 例如。 HTML5工作者線程,或像JavaScriptCore API的上下文對象的多個實例(我假設SpiderMonkey具有類似的概念)。他們不能共享狀態,所以實質上所有的執行都是原子的。

好了,你現在已經提供了一些代碼的我假設你有一個類似於:這種(使用適當的API)

External Process: 
<JSObject>.isRunning = true; 
doSomething() 
<JSObject>.done() 

還是有的。在這種情況下,如果JS在js對象的上下文中執行(這是JavaScriptCore會執行的操作),那麼我會希望JS引擎阻塞,否則您可能需要在js執行周圍放置手動鎖。

你用什麼引擎來完成所有這些工作?我問,因爲根據你的描述,你聽起來像是使用該語言提供的C/C++ API從非JS語言的輔助線程設置標誌,並且大多數JS引擎假定通過API進行的任何狀態操作將發生在單個線程上,通常是發生所有執行的相同線程。

0

我有填充選擇列表的ajax東西,我需要它被鎖定,所以我做了這樣的事情。我認爲你可以做得更簡單,儘管使用延遲和管道等。

var semaphore=[]; 

function myFunc(arg){ 
    var dfd; 
    $.when(semaphore[table]).done(
     function(){ 
      dfd=myFuncInner(arg); 
     } 
    ); 
return dfd; 
} 

function myFuncInner(table){ 
semaphore[arg] = new $.Deferred(); 
... 
somethingasynchronous({ 
    semaphore[arg].resolve(); 
}); 

return semaphore[arg]; 
} 
0

首先,雖然這是事實,JavaScript是單線程的,這是不正確的,沒有序列化機制是有史以來一個JavaScript應用程序所需。

一個簡單的例子,是當一個提交按鈕應該淡出,在此期間一個Ajax請求到服務器工作設定的時間量。當異步Ajax請求成功完成時,一個消息應該出現在按鈕過去的位置。

儘管能夠取消按鈕的淡出並簡單地將它的樣式設置爲「display:none」,但只要Ajax請求完成,這在jQuery中是不可能的。此外,一個解決方案可以使用事件來同步兩個同時進行的活動,但這對於一個簡單的問題本質上是過分的。

一個技術含量低的解決方案是查詢鎖定,當fadeout完成時解鎖,但在$ .post設置的成功回調執行之前,不會顯示「服務器已完成」消息。

var gl_lock; 
var gl_selfID; 

function poll_lock(message) { 
    if (gl_lock === 0) { 
      $('#output').text(message).fadeIn(200); 
      window.clearInterval(gl_selfID); 
    } 
} // end of poll_lock 

function worker() { 

    // no one gets in or out 
    gl_lock = 1; 

    $.post(..., data,function() { 
      gl_selfID = window.setInterval(poll_lock, 40, data.message); 
     }, "json"); 

    // end of fadeout unlock the semaphore 
    $('#submit-button').fadeOut(400, function() { gl_lock = 0; }); 

    } // end of worker 

最後,我想這是更詳細的答案,沿線以前由perrohunter討論建議。