如何提前退出Promises的组合

时间:2016-08-28 12:00:54

标签: javascript promise

我想做这样的事情:

return1stPromise()
  .then(if1stPromiseSucceeds) // returns 2nd Promise
  .catch(if1stPromiseFails)
  .then(if2ndPromiseSucceeds) // execute only if 1st Promise succeeds

我希望第二个.then仅在第一个Promise成功时执行。或者换句话说 - 如果捕获已经执行,我不希望第二个.then执行。

这是否可能,或者我是否已将第二个承诺嵌入第一个then内,如下所示:

return1stPromise()
  .then(function (data) {
    return if1stPromiseSucceeds(data).then(if2ndPromiseSucceeds);
  })
  .catch(if1stPromiseFails);

另外 - 关于如何使用Promises控制流程的任何好资源,它更像是线程?

2 个答案:

答案 0 :(得分:3)

当我们想要对异常作出反应但实际上没有处理它并让代码继续运行时,你所描述的通常就是这种情况:

return1stPromise()
  .then(if1stPromiseSucceeds) // returns 2nd Promise
  .catch(() => { if1stPromiseFails(); throw e; })
  .then(if2ndPromiseSucceeds) // execute only if 1st Promise succeeds

您需要重新抛出异常才能将其标记为"仍未处理"。

这就像同步代码:

try {
  var res = firstResult();
  var res2 = ifFirstPromiseSucceeds(res);
} catch (e) {
    ifFirstPromiseFails();
    throw e; // we reacted to the exception but did not handle it yet.
}
var res3 = ifSecondPromiseSucceeds();

我认为在线程方面考虑承诺大多令人困惑 - 如果可能的话,找到同步类比总是更容易。

这并不总是可行的,例如另一种阻止承诺链的方式是取消这有点像线程中止"我不会&#39关心结果"语义 - 你可以read about it here但我认为对于你的用例它有点超过顶部而不是很好。

答案 1 :(得分:1)

我可能会投掷和捕获,但如果你不想这样做,你总是可以返回被拒绝的承诺,以绕过下一个阶段。如;



new Promise((resolve,reject) => { var rnd = Math.random();
	                              rnd > 0.5 ? resolve(21)
	                                        : reject("promise error");
                                })
    .then(val  => { var rnd = Math.random();
                    if (rnd < 0.5) return Promise.reject("then error");
                    return Promise.resolve(val*2);
                  })
    .catch(err => { console.log(err);
                    return Promise.reject("you won't see this");
                  })
    .then(val  => console.log("Both the promise and the first then stage worked fine and resulted: ", val));
&#13;
&#13;
&#13;

只有在第一个then阶段的第一个承诺和第二个承诺结算时,才会调用最后一个then阶段回调。