似乎從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