链接超时会导致最后一次超时被拒绝

Chaining timeouts results in last timeout rejected?

本文关键字:超时 拒绝 最后一次 链接      更新时间:2023-09-26

我目前正在尝试将一些承诺与超时挂钩,无论达到哪一个超时,它都会报告最后一个。我试过蓝鸟和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个超时,所有超时都要求所有事情(整个链)在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');
});

3秒后,超时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>

从技术上讲,蓝鸟正在履行合同。在规定的时间后,如果承诺没有得到解决,假设没有异常,则被拒绝。无论哪个计时器在这里触发,这都是正确的。这只是对计时器的排序——您应该给它们不同的超时值。

当然,如果在第一个.timeout之后的第一个超时之后添加.catch(function(){})(最好是键入的,而不仅仅是一般的),则会得到不同的结果。

delaytimeout使用环境的setTimeout函数,而在node.js中,该函数绝对不能保证定时器的运行顺序。您基本上需要假设setTimeout(..., 10)可能在setTimeout(..., 10000)之后运行,因此使您的代码依赖于较早的计时器在较晚的计时器中断后运行。