是否有 returns ES6 承诺的 setTimeout 版本?
Is there a version of setTimeout that returns an ES6 promise?
与 this question 类似,但我不想询问 promises 的一般运作方式,我特别想知道:
standard/best 包装 setTimeout in something that returns a Promise? I'm thinking something like Angular's $timeout
function 的方法是什么,但不是 Angular 具体的。
以下是我的实现方式:
function delay(duration, func) {
var args = Array.prototype.slice.call(arguments, 2);
return new Promise(function (resolve) {
setTimeout(function () {
resolve(func.apply(null, args));
}, duration);
});
}
(有意选择的 ES5 语法)
但也许已经有一个公共库可以做到这一点,或者有更好的方法。
在浏览器中
首先没有 - 没有内置的。许多增强 ES2015 承诺的库,例如 bluebird whip with it。
我认为另一个答案将执行函数和延迟混为一谈,它还会造成无法取消的超时。我会简单地写成:
function delay(ms){
var ctr, rej, p = new Promise(function (resolve, reject) {
ctr = setTimeout(resolve, ms);
rej = reject;
});
p.cancel = function(){ clearTimeout(ctr); rej(Error("Cancelled"))};
return p;
}
那么你可以这样做:
delay(1000).then(/* ... do whatever */);
或
doSomething().then(function(){ return delay(1000); }).then(doSomethingElse);
如果我们只想要ES2015中的基本功能,那就更简单了:
let delay = ms => new Promise(r => setTimeout(r, ms));
在节点中
您可以在 setTimeout
上使用 util.promisify
来返回 delay
函数 - 这意味着您不必再使用 new Promise
构造函数。
如果您需要适当的取消承诺超时,类似于clearTimeout
- 直接从setTimeout
返回承诺并不方便。特别是与 ES7 async / await in try...finally
block. It is better to have separate variable for timeout manipulation. I've implemented this approach as tiny await-timeout 包一起使用时。它的工作原理如下:
import Timeout from 'await-timeout';
async function foo() {
const timeout = new Timeout();
try {
const fetchPromise = fetch('https://example.com');
const timerPromise = timeout.set(1000).then(() => console.log('Timeout!'));
await Promise.race([fetchPromise, timerPromise]);
} finally {
timeout.clear();
}
}
在这个例子中,如果获取成功或任何错误,超时肯定会被清除,并且不会调用console.log('Timeout!')
。
与 this question 类似,但我不想询问 promises 的一般运作方式,我特别想知道:
standard/best 包装 setTimeout in something that returns a Promise? I'm thinking something like Angular's $timeout
function 的方法是什么,但不是 Angular 具体的。
以下是我的实现方式:
function delay(duration, func) {
var args = Array.prototype.slice.call(arguments, 2);
return new Promise(function (resolve) {
setTimeout(function () {
resolve(func.apply(null, args));
}, duration);
});
}
(有意选择的 ES5 语法)
但也许已经有一个公共库可以做到这一点,或者有更好的方法。
在浏览器中
首先没有 - 没有内置的。许多增强 ES2015 承诺的库,例如 bluebird whip with it。
我认为另一个答案将执行函数和延迟混为一谈,它还会造成无法取消的超时。我会简单地写成:
function delay(ms){
var ctr, rej, p = new Promise(function (resolve, reject) {
ctr = setTimeout(resolve, ms);
rej = reject;
});
p.cancel = function(){ clearTimeout(ctr); rej(Error("Cancelled"))};
return p;
}
那么你可以这样做:
delay(1000).then(/* ... do whatever */);
或
doSomething().then(function(){ return delay(1000); }).then(doSomethingElse);
如果我们只想要ES2015中的基本功能,那就更简单了:
let delay = ms => new Promise(r => setTimeout(r, ms));
在节点中
您可以在 setTimeout
上使用 util.promisify
来返回 delay
函数 - 这意味着您不必再使用 new Promise
构造函数。
如果您需要适当的取消承诺超时,类似于clearTimeout
- 直接从setTimeout
返回承诺并不方便。特别是与 ES7 async / await in try...finally
block. It is better to have separate variable for timeout manipulation. I've implemented this approach as tiny await-timeout 包一起使用时。它的工作原理如下:
import Timeout from 'await-timeout';
async function foo() {
const timeout = new Timeout();
try {
const fetchPromise = fetch('https://example.com');
const timerPromise = timeout.set(1000).then(() => console.log('Timeout!'));
await Promise.race([fetchPromise, timerPromise]);
} finally {
timeout.clear();
}
}
在这个例子中,如果获取成功或任何错误,超时肯定会被清除,并且不会调用console.log('Timeout!')
。