如何在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调用,这两个函数会消耗相同的结果。