Редактировать 2021 все платформы используют AbortController в качестве примитива отмены, и для этого есть встроенная поддержка.
В Node.js
// import { setTimeout } from 'timers/promises' // in ESM
const { setTimeout } = require('timers/promises');
const ac = new AbortController();
// cancellable timeout
(async () => {
await setTimeout(1000, null, { signal: ac.signal });
})();
// abort the timeout, rejects with an ERR_ABORT
ac.abort();
В браузерах
Вы можете заполнить этот API и использовать то же, что и в примере выше:
function delay(ms, value, { signal } = {}) {
return new Promise((resolve, reject) => {
const listener = () => {
clearTimeout(timer);
reject(new Error('Aborted'));
};
const timer = setTimeout(() => {
signal?.removeEventListener('abort', listener);
resolve(value);
}, ms);
if (signal?.aborted) {
listener();
}
signal?.addEventListener('abort', listener);
});
}
Что вы можете сделать, вы можете вернуть отмену из вашей функции timeout
и вызвать ее при необходимости. Таким образом, вам не нужно хранить timeoutid
глобально (или во внешней области), а также это может управлять несколькими вызовами функции. Каждый экземпляр объекта, возвращаемый функцией timeout
, будет иметь свой собственный отменитель, который может выполнять отмену.
function timeout(ms) {
var timeout, promise;
promise = new Promise(function(resolve, reject) {
timeout = setTimeout(function() {
resolve('timeout done');
}, ms);
});
return {
promise:promise,
cancel:function(){clearTimeout(timeout );} //return a canceller as well
};
}
var timeOutObj =timeout(3000);
timeOutObj.promise.then(function(result) {
console.log(result); // timeout done
});
//Cancel it.
timeOutObj.cancel();
Plnkr
person
PSL
schedule
17.08.2014