首页 > 解决方案 > JavaScript 中的异步事件处理

问题描述

我在防止eventListener代码中的双重(多重)处理方面遇到问题:

var locked;

button.addEventListener("click", function() {
    if (locked) return;
    locked = true;
    calculateSomethingHeavy();
    locked = false;
}

第二次立即按钮单击会触发另一个事件,尽管locked == true. button.disabled = true类似或setTimeout(function() {locked = true;}, 0)没有效果的事情是因为(我猜)第二次调用是堆叠的,并且只有在第一次完全处理后才会被调用。我想我错过了一些异步事件处理的整体技术。如何在纯js中做到这一点?

标签: javascriptasynchronous

解决方案


这里的正确答案取决于 的定义calculateSomethingHeavy。根据问题标题,它可能是异步的,但可以使用回调、事件、承诺或异步/等待来实现。

无论其中哪一个在这里起作用,您需要做的是确保在完成之前locked不会设置为。在每种情况下,这可能如下所示......falsecalculateSomethingHeavy

回调

var locked;

button.addEventListener("click", function() {
    if (locked) return;
    locked = true;
    calculateSomethingHeavy(() => {
        locked = false;
    });
});

活动

var locked;

button.addEventListener("click", function() {
    if (locked) return;
    locked = true;
    calculateSomethingHeavy().on('finish', () => {
        locked = false;
    });
});

承诺

var locked;

button.addEventListener("click", function() {
    if (locked) return;
    locked = true;
    calculateSomethingHeavy()
        .then(() => {
            locked = false;
        });
});

异步/等待

var locked;

button.addEventListener("click", async function() {
    if (locked) return;
    locked = true;
    await calculateSomethingHeavy();
    locked = false;
});

推荐阅读