我可以在蓝鸟Promises的早期打破链条吗?

时间:2015-02-17 22:17:04

标签: javascript promise bluebird

我不一定要错,但我有:

getFromDb().then (tradeData) ->
  if not tradeData
    # DO NOT CONTINUE THE CHAIN
  else
    getLatestPrice tradeData
.then (latestPrice) ->
  ...
.then ->
  ...
.then ->
  ...
.catch (err) ->
  next err

如果没有tradeData,我会以任何方式中止链吗?

3 个答案:

答案 0 :(得分:7)

getFromDb().then (tradeData) ->
  if tradeData
    getLatestPrice tradeData ->
      .then (latestPrice) ->
        ...
      .then ->
        ...
      .then ->
        ...
      .catch (err) ->
        next err
  else
    getSomethingElse ->
       send("no data")

在3.0中,您将能够这样做:

p = getFromDb().then (tradeData) ->
  if not tradeData
    send("no data");
    p.break()
  else
    getLatestPrice tradeData
.then (latestPrice) ->
  ...
.then ->
  ...
.then ->
  ...
.catch (err) ->
  next err

答案 1 :(得分:7)

虽然接受了答案,但我想告诉所有googlers,“break()”函数已更改为“cancel()”

使用这样的东西:

p = getFromDb().then (tradeData) ->
  if not tradeData
    send("no data");
    p.cancel(); // Look Here!!!!!!!!!!!!!!!!
  else
    getLatestPrice tradeData
.then (latestPrice) ->
  ...
.then ->
  ...
.then ->
  ...
.catch (err) ->
  next err

在此之前,请务必在config中添加以下行:

Promise.config({
    cancellation: true
});

答案 2 :(得分:0)

我只是想知道为什么不利用你可以throw任何你喜欢的事实,而不仅仅是instanceof Error。这样做被认为是不好的做法?在我看来,这取决于你想要完成什么。承诺链可能因各种原因而中断,但一般来说这两者可分为两组。需要Classic error occurearly break in chain。逻辑上第二个不能被认为应该是instance of Error

const handleError = (err) => {
  ...
}

const skip = (reason, ..., ...) => {
  /**
   * construct whatever you like
   * just for example here return reason
   */
  return reason
}

Promise.resolve()
.then(() => {
  if (iShouldEndChainEarlier) {
    throw skip('I would like to end chain earlier')
  }

  return asyncOperation1()
})
.then(results => {
  ...
  return asyncOperation2(results)
})
.then(... => {
  ...
})
.catch(interrupt => {
  if (interrupt instanceof Error) {
    return handleError(interrupt)
  }

  /**
   * Handle breaking promise chain earlier
   * having interrupt reason in scope
   */
})

如果逻辑上,链中的早期中断可以被视为错误(完全可以是这种情况),您可以创建自定义错误并区分catch块中的两个。所以只是说在处理承诺链中可能发生的任何中断时,可以考虑另一种方法。

我们可以争辩这可以被视为针对节点中first error pattern的内容。如果出现错误,最佳做法是调用callback(err)之类的回调,其中err确实应该为instanceof Error callback(null, data)。但另一方面考虑到.catch(fn)只是then(undefined, onRejected)给我的糖,根据您所处的情况处理onRejected参数似乎已经足够了。