如何从setTimeout做出承诺
这个问题在这里已经有了答案:
更新(2017)
在2017年,Promises被嵌入到JavaScript中,它们被ES2015规范添加(polyfills可用于过时的环境,如IE8-IE11)。 它们的语法使用一个回调函数传递给Promise
构造函数( Promise
executor),该函数接收解析/拒绝promise的函数作为参数。
首先,由于async
现在在JavaScript中有意义(即使它只是某些上下文中的关键字),我将later
用作函数的名称以避免混淆。
基本延迟
使用本地承诺(或忠实的polyfill)它看起来像这样:
function later(delay) {
return new Promise(function(resolve) {
setTimeout(resolve, delay);
});
}
请注意,假定setTimeout
的版本符合浏览器的定义,其中setTimeout
不会将任何参数传递给回调,除非您在时间间隔后给予它们(这在非浏览器环境中可能不是这样,并且未使用在Firefox上是真实的,但是现在;在Chrome上甚至在IE8上都是如此)。
具有价值的基本延迟
如果你希望你的函数有选择地传递一个分辨率值,那么在任何模糊的现代浏览器上,你可以在延迟后给setTimeout
额外的参数,然后在被调用时将它们传递给回调函数,你可以这样做(当前的Firefox和Chrome; IE11 +,想必Edge; 不是 IE8或IE9,不知道IE10):
function later(delay, value) {
return new Promise(function(resolve) {
setTimeout(resolve, delay, value); // Note the order, `delay` before `value`
/* Or for outdated browsers that don't support doing that:
setTimeout(function() {
resolve(value);
}, delay);
Or alternately:
setTimeout(resolve.bind(null, value), delay);
*/
});
}
如果您使用ES2015 +箭头功能,可以更简洁:
function later(delay, value) {
return new Promise(resolve => setTimeout(resolve, delay, value));
}
甚至
const later = (delay, value) =>
new Promise(resolve => setTimeout(resolve, delay, value));
可取消的延迟与值
如果您希望使取消超时成为可能,那么您不能仅仅从later
返回承诺,因为承诺不能被取消。
但是我们可以很容易地使用cancel
方法和承诺的访问者返回对象,并在取消时拒绝承诺:
const later = (delay, value) => {
let timer = 0;
let reject = null;
const promise = new Promise((resolve, _reject) => {
reject = _reject;
timer = setTimeout(resolve, delay, value);
});
return {
get promise() { return promise; },
cancel() {
if (timer) {
clearTimeout(timer);
timer = 0;
reject();
reject = null;
}
}
};
};
现场示例:
const later = (delay, value) => {
let timer = 0;
let reject = null;
const promise = new Promise((resolve, _reject) => {
reject = _reject;
timer = setTimeout(resolve, delay, value);
});
return {
get promise() { return promise; },
cancel() {
if (timer) {
clearTimeout(timer);
timer = 0;
reject();
reject = null;
}
}
};
};
const l1 = later(100, "l1");
l1.promise
.then(msg => { console.log(msg); })
.catch(() => { console.log("l1 cancelled"); });
const l2 = later(200, "l2");
l2.promise
.then(msg => { console.log(msg); })
.catch(() => { console.log("l2 cancelled"); });
setTimeout(() => {
l2.cancel();
}, 150);
链接地址: http://www.djcxy.com/p/55509.html