我正在创建一个脚本,该脚本将在经过一定时间后执行任务。我希望用户能够取消执行这些任务。为此,我可以将超时保存到列表中,然后使用该列表来取消所有超时。但是,如果超时正常完成,它仍将存储在该列表中。
如何在尝试清除超时之前检查超时是否已完成或取消?
var timeouts = [];
$(document).on('click', '.doTask', function() {
var timeout = setTimeout(() => {
doTaskAfter();
}, 10000);
timeouts.push(timeout);
});
$(document).on('click', '.cancelTasks', function() {
var i = timeouts.length;
while (i--) {
if (timeouts[i].finished || timeouts[i].timeoutCleared) { // How to I check this?
clearTimeout(timeouts[i]);
}
timeouts.splice(i, 1);
}
});
答案 0 :(得分:1)
我认为您可以使用诺言做到这一点。
每次创建计时器时,将其放入promise中,然后将该promise推入数组。一旦计时器运行,诺言就会解决。
从字面上写您的计时器。.
setTimeout(() => {
resolve("True");
}, 10000);
从那里开始,您可以执行此操作。当您遍历代码时,请使用promise.race,以及第二个返回false的promise。
let race = [timeouts[i],Promise.resolve("False") ]
使用Promise.race查找承诺是否已解决。之所以可行,是因为如果他们两个都解决了,Promise.race将返回第一个Promise,后者将返回“ True”。如果您的计时器仍未使用,则它将返回false。
Promise.race(race).then((res, rej) => {
if(res === true) {
clearTimeout(timeouts[i]);
}
})
答案 1 :(得分:0)
我不知道我是否理解正确,但是为什么要删除已经完成的超时?
超时可以在完成后将其自身从数组中删除:
timeouts.splice(timeouts.indexOf(timeout), 1);
否则,您可以使用clearTimeout
和splice
从超时列表中杀死所有已注册/正在运行的超时。
var timeouts = [];
$(document).on('click', '.doTask', function() {
var timeout = setTimeout(() => {
doTaskAfter();
timeouts.splice(timeouts.indexOf(timeout), 1); // <=== HERE
}, 10000);
timeouts.push(timeout);
});
$(document).on('click', '.cancelTasks', function() {
var i = timeouts.length;
while (i--) {
clearTimeout(timeouts[i]);
timeouts.splice(i, 1);
}
});
答案 2 :(得分:0)
可能或不重要的一件事是,在已经清除或完成的超时doesn't do anything上调用clearTimeout
,因此您可能不需要跟踪它。
否则,您可以跟踪状态,例如:
var timeouts = [];
$(document).on('click', '.doTask', function() {
var timeout = { state: 'waiting' };
timeout.id = setTimeout(() => {
timeout.state = 'finished';
doTaskAfter();
}, 10000);
timeouts.push(timeout);
});
$(document).on('click', '.cancelTasks', function() {
var i = timeouts.length;
while (i--) {
if (timeouts[i].state !== 'finished' && timeouts[i].state !== 'canceled') {
// i.e. timeouts[i].state is 'waiting'
clearTimeout(timeouts[i].id);
timeouts[i].state = 'canceled';
}
timeouts.splice(i, 1);
}
});
答案 3 :(得分:0)
只需将包含您需要执行的代码的函数放在设置的超时内,就像这样:
setTimeout(() => { youfunction()}, 2000)
yourfunction(){
put your code here
}
yourfunction
将在2秒后执行。