我不一定要错,但我有:
getFromDb().then (tradeData) ->
if not tradeData
# DO NOT CONTINUE THE CHAIN
else
getLatestPrice tradeData
.then (latestPrice) ->
...
.then ->
...
.then ->
...
.catch (err) ->
next err
如果没有tradeData,我会以任何方式中止链吗?
答案 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 occur
和early 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
参数似乎已经足够了。