如何在 JavaScript 中实现锁

新手上路,请多包涵

如何用 JavaScript 实现 C# 中相当于 lock 的东西?

因此,为了解释我的想法,一个简单的用例是:

用户点击按钮 BB 引发 onclick 事件。 If B is in event-state the event waits for B to be in ready-state before propagating. If B is in ready-state , B is locked and is set to event-state , then the event propagates.事件传播完成后, B 设置为 ready-state

我可以看到如何完成类似的操作,只需从按钮中添加和删除类 ready-state 即可。然而,问题在于用户连续两次单击按钮的速度快于设置变量的速度,因此这种锁定尝试在某些情况下会失败。

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

原文由 smartcaveman 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 842
2 个回答

Lock 在 JS 中是一个值得怀疑的想法,它旨在实现无线程且不需要并发保护。您希望结合延迟执行的调用。我为此遵循的模式是使用回调。是这样的:

 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 解决方案来实现它。

原文由 JoshRivers 发布,翻译遵循 CC BY-SA 3.0 许可协议

JavaScript 是,除了极少数 例外XMLHttpRequest onreadystatechange 某些版本的 Firefox 中的处理程序) 事件循环并发。所以你不必担心在这种情况下锁定。

JavaScript 有一个基于“事件循环”的并发模型。该模型与其他语言(如 C 或 Java)中的模型有很大不同。

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

在处理任何其他消息之前,每条消息都会被完全处理。 这在推理您的程序时提供了一些很好的属性,包括这样一个事实:无论何时函数运行,它都不能被抢占,并且会在任何其他代码运行之前完全运行(并且可以修改函数操作的数据)。 这与 C 不同,例如,如果一个函数在一个线程中运行,它可以随时停止以在另一个线程中运行一些其他代码。

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

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

原文由 Mike Samuel 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题