似乎从tap
处理程序返回值p.cancel()
的行为正在导致蓝鸟进入某种无限循环。您从不会看到第二个'callback!'
,因为执行上下文在100 ms过去之前会停留在此循环中。
我仍然离这里不远的理解所有的因素在起作用(见下文),但它看起来像这样可以不返回p.cancel()
固定:
Promise = require 'bluebird'
cb = ->
console.log 'callback!'
p = Promise.resolve(5)
.cancellable()
.tap ->
p.cancel()
null
setInterval(cb, 100)
编辑:好,照顾在源和unknotting我的大脑了几下,我认为它归结为:
执行被卡在这里了无限循环,其中.cancel()
试图爬上承诺链:
while ((parent = promiseToReject._cancellationParent) !== undefined &&
parent.isCancellable()) {
promiseToReject = parent;
}
分
的要点如下:
p.cancel()
回报p
。
.tap()
返回解析时的承诺从它的处理程序做出决议返回(如果它返回一个承诺)
p
是承诺,.tap()
回报
换句话说,p
是一种承诺,将承诺在p
解决后解决。它是承诺链中的自己的祖先(至少,我认为是这样)。
.cancel()
当.cancel()
试图爬上承诺链来寻找一个可以取消的承诺时,它发生在这个乱伦关系上,并开始永远循环。最后,这是CoffeeScript渴望将几乎所有东西都变为return
声明的一个不幸后果。但我可以想象,Bluebird可以通过某种方式检测承诺链中的循环,并防止发生无限循环。
我已经在蓝鸟GitHub存储库上提交了一个issue,但是随后的讨论揭示,.cancel()
的这种使用根本没有任何意义。
我刚刚运行一个简单的测试,并从'setInterval()'回调中抛出一个异常不会停止计时器,因此看起来并不相关。 – jfriend00 2015-03-02 16:11:46