JS:检查setTimeout是否已完成或被取消

时间:2019-02-05 22:54:48

标签: javascript

我正在创建一个脚本,该脚本将在经过一定时间后执行任务。我希望用户能够取消执行这些任务。为此,我可以将超时保存到列表中,然后使用该列表来取消所有超时。但是,如果超时正常完成,它仍将存储在该列表中。

如何在尝试清除超时之前检查超时是否已完成或取消?

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);
    }
});

4 个答案:

答案 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);

否则,您可以使用clearTimeoutsplice从超时列表中杀死所有已注册/正在运行的超时。

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秒后执行。