如何在JavaScript中实现锁定

sma*_*man 72 javascript events deadlock locking javascript-events

如何lock在JavaScript中实现与C#相同的东西?

所以,要解释我在想什么简单的用例是:

用户点击按钮B. B提出onclick事件.如果B是在event-state事件等待B是在ready-state传播之前.如果B处于ready-state,B已锁定并设置为event-state,则事件将传播.事件的传播完成后,B设置为ready-state.

我可以看到如何通过添加和删除ready-state按钮中的类来完成与此相近的操作.但是,问题是用户可以连续两次单击按钮,而不是可以设置变量,因此在某些情况下锁定尝试将失败.

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

Jos*_*ers 81

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);
             }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

您还可以使用DOM事件侦听器或pubsub解决方案来实现此功能.

  • 你能不能请你提供参考文件证明你的陈述"JS是无线的,不需要并发保护"?我想更多地了解这一点. (11认同)
  • 什么库是$ .longRunning来自?它不在(当前)jQuery中. (3认同)
  • 什么时候设置functionLock? (3认同)
  • +1 - 鉴于Node.js(JavaScript Web服务器)是为了利用JavaScript的单线程和回调机制而构建的,我同意您不必担心锁定属性,因为没有竞争条件. (2认同)
  • “旨在无线程且不需要并发的JS”令人怀疑。JS不使用抢占式并发,但允许您使用协作式并发(基于回调或基于异步/等待)。使用这些条件时,您绝对可以具有竞争条件,并且可能希望使用互斥体抽象来避免它们。 (2认同)

Mik*_*uel 30

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

JavaScript具有基于"事件循环"的并发模型.此模型与其他语言(如C或Java)中的模型完全不同.

...

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

...

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

此模型的缺点是,如果消息需要很长时间才能完成,则Web应用程序无法处理用户交互,例如单击或滚动.浏览器通过"脚本运行时间太长"对话框来缓解此问题.遵循的一个好习惯是使消息处理简短,如果可能,将一条消息剪切成若干消息.

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


Wic*_*nga 14

如果它对 2022 年以后的任何人有帮助的话,所有主要浏览器现在都支持Web Locks API,尽管还处于实验阶段。

引用MDN中的例子:

await do_something_without_lock();

// Request the lock.
await navigator.locks.request('my_resource', async (lock) => {
  // The lock has been acquired.
  await do_something_with_lock();
  await do_something_else_with_lock();
  // Now the lock will be released.
});
// The lock has been released.

await do_something_else_without_lock();
Run Code Online (Sandbox Code Playgroud)
  • 回调返回时锁自动释放
  • 锁的范围仅限于源 ( https://example.com!= https://example.org:8080),并且跨选项卡/工作人员工作。
  • 锁定请求排队(先到先服务);(与其他一些语言不同,锁被随机传递给某个线程)
  • navigator.locks.query()可以用来查看什么拥有锁,以及谁在队列中获取锁
  • 如果需要的话,可以mode="shared"实现读写锁


Tim*_*ott 7

我有成功的互斥承诺.

我同意你可能不需要锁定的其他答案.但是,从来没有人需要锁定Javascript.在访问不处理并发的外部资源时,您需要互斥.


Jam*_*ate 6

锁是多线程系统中所需的概念.即使使用工作线程,也会在工作程序之间按值发送消息,因此不需要锁定.

我怀疑你需要在你的按钮之间设置一个信号量(标记系统).

  • 就在这里,也就是http://stackoverflow.com/questions/4194346/how-to-create-semaphore-between-html-elements-loaded-async (4认同)