承诺和流量控制:提前退出

Promises and flow control: Early exit

我最近开始在 coffeescript/javascript 中编写 promise 代码,我喜欢它。我不明白的一件事是如何用承诺处理流量控制。考虑以下带有 Q.

的代码
outerFunction = ->
  Q()
    .then ->
      doSomethingAsync
    .then (result) ->
      return result if result is someSpecialValue 
      #do I really have to continue this chain or nest my promises in a new promise chain?
      ...
    .then ->
      ...
    .then ->
      ...

我想return早点给来电者打电话。这甚至可能吗?

我不想使用魔法异常来进行流量控制。我需要做这样的事情还是有更好的方法?

...
.then (result) ->
  return result if result is someSpecialValue
  return Q()
    .then -> 
      ...
    .then -> 
      ...

这里有一个更完整的答案,return不可能给来电者打电话。因为 Promise 是 运行 异步的...换句话说,当 Promise 开始工作时,调用者已经 returned。所以 return 不可能给来电者打电话,因为来电者已经走了。

如果你想离开承诺,你可以简单地调用 this.reject() 你可以用参数拒绝。它会陷入 catch 承诺。如果您不想再处理 then,您也可以从 catch 子句中 reject。然后在某些时候,这将导致承诺失败。

它可能不会完全按照您的要求进行,因为您必须至少在最后 catch 处理错误或您提前离开承诺的原因。但即使是 catch 也是一个承诺。

outerFunction = ->
  Q()
    .then ->
      doSomethingAsync
    .then (result) ->

      if error
         this.reject(result)

      return result if result is someSpecialValue 

    .then ->
      ...
    .then ->
      ...
    .catch (error) ->
      console.log("Handling error", error)

这里有更多关于承诺的文档:http://promisejs.org/这是一本好书。

我希望您明白 using 拒绝非常类似于通过引发异常来尝试提前退出堆栈函数对。我不鼓励这样做,因为它可能非常糟糕并且很难理解其背后的逻辑。如果即使没有异常或错误也必须提前退出承诺,那么您可能必须重新考虑流程。

你可以做的是:

outerFunction = ->
  Q()
    .then ->
      doSomethingAsync
    .then (result) ->

      if return_now
         return result if result is someSpecialValue
      return Q()
         .then ->
           ...
         .then ->
           ...
         .then ->
           ...

您可以return您的结果或return一个将继续流程链的承诺。