2021年修改:所有平台都已经使用AbortController作为取消原语,并且已经内置了对此的支持。
在Node.js中
const { setTimeout } = require('timers/promises');
const ac = new AbortController();
(async () => {
await setTimeout(1000, null, { signal: ac.signal });
})();
ac.abort();
在浏览器中
您可以使用 polyfill 实现该 API 并将其用作上面示例中的代码:
function delay(ms, value, { signal } = {}) {
return new Promise((resolve, reject) => {
const listener = () => {
clearTimeout(timer);
reject(signal.reason);
};
signal?.throwIfAborted();
const timer = setTimeout(() => {
signal?.removeEventListener('abort', listener);
resolve(value);
}, ms);
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 );}
};
}
var timeOutObj =timeout(3000);
timeOutObj.promise.then(function(result) {
console.log(result);
});
timeOutObj.cancel();
Plnkr