链接超时导致上次超时被拒绝?

时间:2015-02-12 09:47:19

标签: javascript node.js promise q bluebird

我目前正试图通过超时链接一些承诺,无论达到哪个超时,它总是报告最后一个。我用bluebird和Q尝试了相同的结果,所以我认为我有一个普遍的问题。

代码基本上如下所示:

var Promise = require('bluebird');

Promise.delay(2000)
  .then(function() {
    return Promise.delay(2000);
  })
  .timeout(1000, 'Timeout 1')
  .then(function() {
    return Promise.delay(500);
  })
  .timeout(1000, 'Timeout 2')
  .then(function() {
    return Promise.delay(500);
  })
  .timeout(1000, 'Timeout 3');

我收到“未处理的拒绝超时错误:超时3”。我想要的是获得超时1.我在每次超时后尝试捕捉,但我也得到了相同的结果。

有没有办法让它工作而不完整地拆分它?

3 个答案:

答案 0 :(得分:1)

Bluebird不保证计时器的执行顺序。因此,如果您将三个超时设置为相同的时间跨度,我们就不会强制执行哪一个超时。正如您所看到的,如果您在浏览器中运行此代码"Timeout 1"将记录而不是超时3:



var p = Promise.delay(2000)
  .then(function() {
    return Promise.delay(2000);
  })
  .timeout(1000, 'Timeout 1')
  .then(function() {
    return Promise.delay(500);
  })
  .timeout(1000, 'Timeout 2')
  .then(function() {
    return Promise.delay(500);
  })
  .timeout(1000, 'Timeout 3');

p.reflect().then(function(res){
  document.body.innerHTML = JSON.stringify(res.reason().message);
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.6/bluebird.js"></script>
&#13;
&#13;
&#13;

技术上蓝鸟正在保持合同。如果承诺尚未解决,假定没有异常,则在规定的时间后,它将被拒绝。无论在哪个计时器触发,都是如此。 这只是定时器的排序 - 你应该给它们不同的超时值。

当然,如果您在第一次.catch(function(){})之后的第一次超时后添加.timeout(最好是输入一次而不只是一般),您将获得不同的结果。

答案 1 :(得分:1)

目前你有3次超时,都要求所有东西(你的整个链条)在1秒内完成。
我觉得你真的想为每个连续的任务做3次超时:

Promise.delay(2000)
.then(function() {
    return Promise.delay(2000)
    .timeout(1000, 'Timeout 1');
})
.then(function() {
    return Promise.delay(500)
    .timeout(1000, 'Timeout 2');
})
.then(function() {
    return Promise.delay(500)
    .timeout(1000, 'Timeout 3');
});

在超时1的3秒后,这将被拒绝。

答案 2 :(得分:0)

delaytimeout使用环境的setTimeout函数,node.js中的函数绝对不能保证计时器的运行顺序。你基本上需要假设一个setTimeout(..., 10)可能会在setTimeout(..., 10000)之后运行,这样你的代码就会依赖早期的计时器来在以后的计时器中断之后运行。