我知道Q有一个promise timeout,但我使用的是原生NodeJS promise,它们没有.timeout函数。
是我漏了一个还是它的 Package 不同?
或者,下面的实现在不占用内存的情况下是否很好,实际上是否按预期工作?
另外,我可以让它以某种方式全局 Package ,这样我就可以在我创建的每个promise中使用它,而不必重复setlog和clearlog代码?
function run() {
logger.info('DoNothingController working on process id {0}...'.format(process.pid));
myPromise(4000)
.then(function() {
logger.info('Successful!');
})
.catch(function(error) {
logger.error('Failed! ' + error);
});
}
function myPromise(ms) {
return new Promise(function(resolve, reject) {
var hasValueReturned;
var promiseTimeout = setTimeout(function() {
if (!hasValueReturned) {
reject('Promise timed out after ' + ms + ' ms');
}
}, ms);
// Do something, for example for testing purposes
setTimeout(function() {
resolve();
clearTimeout(promiseTimeout);
}, ms - 2000);
});
}
字符串
谢谢你,谢谢
8条答案
按热度按时间col17t5w1#
原生JavaScript promise没有任何超时机制。
关于您的实现的问题可能更适合http://codereview.stackexchange.com,但有几个注意事项:
1.在promise中,你没有提供一种实际做任何事情的方法,
1.在
setTimeout
回调中不需要clearTimeout
,因为setTimeout
调度一个一次性计时器。1.因为一旦promise被resolved/rejected,它就不能被resolved/rejected,所以你不需要检查。
所以继续你的
myPromise
函数方法,可能是这样的:字符串
使用方式如下:
型
(Or可能稍微不那么复杂,请参阅下面的分隔符。)
我有点担心语义不同的事实(没有
new
,而你确实使用Promise
构造函数的new
),但更大的问题是,它假设你总是从头开始创建一个promise,但你通常希望能够使用你已经拥有的promise。您可以通过子类化
Promise
来处理这两个问题:型
用法(如果构造一个新的promise):
型
用法(如果使用你已经拥有的promise):
型
示例:
的字符串
上面的代码在解析或拒绝promise时主动取消了计时器。根据你的用例,这可能不是必要的,并且使代码有点复杂。这对promise部分没有必要;一旦promise被解决或拒绝,就不能改变,再次调用
resolve
或reject
函数对promise没有影响(规范对此很清楚)。但是如果你不取消计时器,计时器在触发之前仍然是挂起的。挂起的promise将阻止Node.js退出,例如,所以如果你在最后一件事上做了一个很长的超时,它可能会延迟退出进程。浏览器不会延迟离开页面与挂起的计时器,所以这不适用于浏览器。所以再次,你的里程可能会有所不同,你可以通过不取消计时器来简化一点。如果你不关心挂起计时器,
MyPromise
会更简单:型
z5btuh9x2#
要向任何现有promise添加超时,您可以使用:用途:
字符串
再后来:
型
kuarbcqp3#
虽然可能没有对promise超时的支持,但您可以竞赛promise:
字符串
一个通用的
Promise.timeout
:型
范例:
型
可能会有一点代价,因为你实际上创建了3个promise而不是2个。
你可能想设置一个promise,而不是让函数为你构造它。这样你就可以分离关注点,最终你可以专注于与一个新构建的promise竞争,这个新构建的promise将在
x
毫秒时被拒绝。型
用途:
型
gblwokeq4#
这是一个有点老的问题,但是我在研究如何超时一个promise时偶然发现了这个问题。
虽然所有的答案都很好,但我发现使用Promises的bluebird实现是handling timeouts的最简单方法:
字符串
正如你所看到的,这比其他提出的解决方案少了很多工作。我想我会把它放在这里,让人们更容易找到它:)
顺便说一句,我没有参与任何蓝鸟项目,只是发现这个特殊的解决方案非常整洁。
ncecgwcz5#
Extension Method是一种方便的解决方案:
字符串
这是通过向Promise global object的原型添加一个方法来实现的。“
promiseWithTimeout.js
:型
为了获得TypeScript支持,请在定义
Promise.prototype.withTimeout
之前添加以下声明块:型
tgabmvqs6#
如果你的代码被放在一个类中,你可以使用一个装饰器。你在utils-decorators库(
npm install --save utils-decorators
)中有这样的装饰器:字符串
或者你可以使用一个wrapper函数:
型
ldfqzlk87#
虽然这里的答案是有效的,但你不应该试图重新发明轮子,而只是使用NPM上的几十个可用包中的一个来实现自我解决的承诺。
下面是一个example from NPM:
字符串
pb3s4cty8#
在这种情况下, Package 器会很方便
用法
字符串
或
型
或甚至
型
实现
型