如何在JavaScript中实现一个锁

如何在JavaScript中实现等同于C#的lock

所以,解释一下我在想一个简单的用例是:

用户点击buttonB B提出了一个onclick事件。 如果B处于event-state则事件在传播之前等待B处于ready-state 。 如果B处于ready-state ,则B被locking并被设置为event-state ,然后事件传播。 当事件的传播完成时, B被设置为ready-state

我可以看到如何接近这个可以完成,只需要添加和删除buttonready-state 。 但是,问题在于用户可以在一行中点击一个button的次数比可以设置的variables快两倍,所以在某些情况下,locking的尝试将失败。

有谁知道如何实现一个不会在JavaScript中失败的锁?

JS在JS中是一个值得怀疑的想法,它是无线的,不需要并发保护。 您正在寻找结合延期执行的调用。 我遵循的模式是使用callback。 像这样的东西:

 var functionLock = false; var functionCallbacks = []; var lockingFunction = function (callback) { if (functionLock) { functionCallbacks.push(callback); } else { $.longRunning(function(response) { while(functionCallbacks.length){ var thisCallback = functionCallbacks.pop(); thisCallback(response); } }); } } 

您也可以使用DOM事件侦听器或pubsub解决scheme来实现这一点。

JavaScript是less数例外 (某些版本的Firefox的XMLHttpRequest onreadystatechange处理程序) 事件循环并发 。 所以你不必担心在这种情况下locking。

JavaScript有一个基于“事件循环”的并发模型。 这个模型与C或Java等其他语言的模型完全不同。

JavaScript运行时包含一个消息队列,它是要处理的消息列表。 为每个消息关联一个函数。 当堆栈为空时,将从队列中取出一条消息并进行处理。 处理包括调用相关函数(从而创build一个初始堆栈帧)。当堆栈再次变空时,消息处理结束。

在处理任何其他消息之前,每个消息都被完全处理。 这在推理你的程序的时候提供了一些很好的属性,包括每当一个函数运行的时候,它不能被抢占,并且会在任何其他代码运行之前完全运行(并且可以修改该函数处理的数据)。 这与C不同,例如,如果某个函数在一个线程中运行,那么可以在任何时候停止运行另一个线程中的其他代码。

这种模式的一个缺点是,如果一条消息需要很长时间才能完成,那么Web应用程序将无法处理像点击或滚动这样的用户交互。 浏览器通过“脚本运行时间太长”对话框缓解这种情况。 一个很好的做法是使消息处理简短,如果可能的话,把一条消息分成几条消息。

有关事件循环并发的更多链接,请参阅E

锁是multithreading系统中需要的概念。 即使使用工作线程,消息也是通过工作人员之间的值发送的,因此不需要locking。

我怀疑你需要在你的button之间设置一个信号(标记系统)。

为什么不closuresbutton并在完成事件后启用它?

 <input type="button" id="xx" onclick="checkEnableSubmit('true');yourFunction();"> <script type="text/javascript"> function checkEnableSubmit(status) { document.getElementById("xx").disabled = status; } function yourFunction(){ //add your functionality checkEnableSubmit('false'); } </script> 

快乐编码!

我有成功的互斥诺言 。

我同意其他答案,你可能不需要在你的情况下locking。 但是,从来没有人需要在Javascript中进行locking。 访问不处理并发的外部资源时,您需要相互独享。

根据我的情况,JoshRiver的答案有所增加;

 var functionCallbacks = []; var functionLock = false; var getData = function (url, callback) { if (functionLock) { functionCallbacks.push(callback); } else { functionLock = true; functionCallbacks.push(callback); $.getJSON(url, function (data) { while (functionCallbacks.length) { var thisCallback = functionCallbacks.pop(); thisCallback(data); } functionLock = false; }); } }; // Usage getData("api/orders",function(data){ barChart(data); }); getData("api/orders",function(data){ lineChart(data); }); 

只会有一个API调用,这两个函数会消耗相同的结果。