蓝鸟承诺并抓住分支

时间:2015-04-01 10:04:39

标签: javascript node.js try-catch promise bluebird

我想知道Bluebird是否有办法承诺.catch抛出错误,然后处理一些没有分支的特定操作(嵌套承诺)。

说我有

doSomethingAsync()
.then(function (result) {
  if (!result)
    throw new CustomError('Blah Blah');

  if (result == 0)
    throw new CustomError2('Blah Blah Blah');

  return result;
})
.then(function (result) {
  console.log('Success, great!');
})

.catch(CustomError, function (error) {
  // Oh CustomError!
  return saveSomethingAsync();
})
.then(function (saved) {
  // Should only be executed if an CustomError has been thrown
  console.log("Let's try again");
  return doSomethingAsync();
})

.catch(CustomError2, function (error) {
  // Oh CustomError2!
})
.delay(15000) // Don't try again now !
.then(function () {
  // Should only be executed if an CustomError2 has been thrown
  console.log("Let's try again after some long delay");
  return doSomethingAsync();
})

.catch(function (error) {
  // Should catch all random errors of the chain
})

当我执行此代码时,我会得到几个行为:

  • 如果没有错误,我会“成功,太棒了!”它再次以“让我们在经过一段长时间的延迟后再试”
  • 开始
  • 如果CustomError抛出,我会“让我们再试一次”
  • 如果CustomError2抛出,我会得到“让我们在经过一段长时间的延迟后再试”

我无法弄清楚这个流程发生了什么。 写这样的东西应该很棒,而不是将错误的特定代码嵌套在新的承诺链中。

1 个答案:

答案 0 :(得分:1)

  

.catch抛出错误然后处理一些特定的操作而不进行分支

没有。因为 分支。嵌套在这里是完全自然的。您甚至可以使用同步 - try-catch隐喻来考虑这一点,它将是相同的。

  

我无法弄清楚这种情况发生了什么。

     
      
  • 如果没有错误,我会得到成功,很棒!"然后再次开始"让我们在经过一段长时间的延迟后再试一次#34;
  •   
嗯,这很奇怪,因为"让我们再试一次" (没有延迟)在此之前被链接。你最终应该得到两个日志。您的连锁店按顺序处理:

doSomethingAsync() // returns a result
 then return result // first callback: continues with it
 then console.log('Success, great!') // next callback: logs something
 catch // is ignored because no rejection
 then console.log("Let's try again"); // next callback: logs something
      return doSomethingAsync();      //                and returns a result
 catch // that result, not being a rejection, is ignored here
 delay // fulfillment is delayed
 then console.log("Let's try again after some long delay"); // next callback again logs
      return doSomethingAsync();                            // and returns a result
 catch // is ignored again
  
      
  • 如果抛出CustomError,我会再次尝试#34;
  •   

是的,因为前一个承诺的结果saveSomethingAsync();已经完成,所以链中的下一个.then()回调会执行。

  
      
  • 如果抛出CustomError2,我会得到"让我们在经过一段长时间的延迟后再试一次"
  •   

是的,因为错误一直到最终处理的.catch(CustomError2, …)。在途中,没有执行回调。在the error was handled之后,承诺得以实现,链中的下一个.then()会调用其回调。

我认为你真正想要的是

doSomethingAsync()
.then(function(result) {
  if (!result)
    // CustomError('Blah Blah');
    // Oh CustomError!
    return saveSomethingAsync();
    .then(function(saved) {
      console.log("Let's try again");
      return doSomethingAsync();
    });
  else if (result == 0)
    // CustomError2('Blah Blah Blah');
    // Oh CustomError2!
    return Promise.delay(15000) // Don't try again now !
    .then(function() {
      console.log("Let's try again after some long delay");
      return doSomethingAsync();
    })
  else
    console.log('Success, great!');
  // return undefined implied
}).catch(function (error) {
  // does catch all random errors of the chain
  // thrown by any of the doSomethingAsync() or of the saveSomethingAsync
})