2009-02-17 74 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讨论建议。