admin管理员组文章数量:1334656
I have an issue with preventing double (multiple) eventListener
handling in code:
var locked;
button.addEventListener("click", function() {
if (locked) return;
locked = true;
calculateSomethingHeavy();
locked = false;
}
Second immediate button click triggers another event, despite locked == true
. Things like button.disabled = true
or setTimeout(function() {locked = true;}, 0)
have no effect because (I guess) second call is stacked and will be invoked only after first is fully handled. I think I'm missing some whole technology of asynchronous event handling. How to do this in pure js?
I have an issue with preventing double (multiple) eventListener
handling in code:
var locked;
button.addEventListener("click", function() {
if (locked) return;
locked = true;
calculateSomethingHeavy();
locked = false;
}
Second immediate button click triggers another event, despite locked == true
. Things like button.disabled = true
or setTimeout(function() {locked = true;}, 0)
have no effect because (I guess) second call is stacked and will be invoked only after first is fully handled. I think I'm missing some whole technology of asynchronous event handling. How to do this in pure js?
-
1
Is
calculateSomethingHeavy
heavy or asynchronous (or both)? Those are very distinct concepts – CertainPerformance Commented Jul 8, 2018 at 20:22 -
1
If
calculateSomethingHeavy
is meant to be asynchronous and you needlocked
to be set to false after it pletes, then you need to return a Promise fromcalculateSomethingHeavy
and set locked to false in its success handler. As written, this is synchronous code, so locked will be set to false immediately aftercalculateSomethingHeavy
is called. – Daniel Beck Commented Jul 8, 2018 at 20:40 -
Actually,
calculateSomethingHeavy
is a bit tricky - the function fills a big canvas with pixels and after its first call it timeouts itself 99 more times to give some time for refreshing progress bars on the page (so each function call does 1% of all calculations). But the thing is,eventListener
behaviour doesn't depend on existence of those timeouts, so I put simplified version here (I hope solution also doesn' depend on that) – Roman Sergeev Commented Jul 9, 2018 at 21:50
1 Answer
Reset to default 7The correct answer here depends on the definition of calculateSomethingHeavy
. Presumably it's asynchronous based on the question title, but that could be implemented using callbacks, or events, or promises or async/await.
Regardless of which of those is at play here, what you need to do is ensure that locked
is not set to false
until after calculateSomethingHeavy
has finished.
That might look like the following in each case...
Callbacks
var locked;
button.addEventListener("click", function() {
if (locked) return;
locked = true;
calculateSomethingHeavy(() => {
locked = false;
});
});
Events
var locked;
button.addEventListener("click", function() {
if (locked) return;
locked = true;
calculateSomethingHeavy().on('finish', () => {
locked = false;
});
});
Promises
var locked;
button.addEventListener("click", function() {
if (locked) return;
locked = true;
calculateSomethingHeavy()
.then(() => {
locked = false;
});
});
async/await
var locked;
button.addEventListener("click", async function() {
if (locked) return;
locked = true;
await calculateSomethingHeavy();
locked = false;
});
本文标签: Asynchronous event handling in JavaScriptStack Overflow
版权声明:本文标题:Asynchronous event handling in JavaScript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742372309a2462470.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论