[英]Exception gets swallowed in promise chain
當Parse for React Native中的一系列promise中拋出異常時,我注意到發生了一些非常奇怪的事情。 承諾鏈永遠不會解決,永遠不會拒絕,並且永遠不會拋出異常。 它只是默默地消失。
這是重新創建問題的示例代碼:
// Replacing this with Promise.resolve() prints the error.
// Removing this stage prints the error.
Parse.Promise.as()
// Removing this stage causes a red screen error.
.then(function() {
// Replacing this with Parse.Promise.as() causes a red screen error.
return Promise.resolve();
})
.then(function () {
throw new Error("There was a failure");
})
.then(function () { console.log("Success")}, function (err) { console.log(err) });
正如您從評論中看到的那樣,它似乎只發生在這個特定的事件序列中。 刪除一個階段,或者交換一個原生JS承諾的Parse承諾,會導致事情再次發生。 (在我的實際代碼中,“Promise.resolve()”階段實際上是對返回promise的本機iOS方法的調用。)
我知道Parse承諾的行為與A +兼容的承諾完全不同 (參見https://stackoverflow.com/a/31223217/2397068 )。 實際上,在此代碼段之前調用Parse.Promise.enableAPlusCompliant()
會導致捕獲並打印異常。 但我認為Parse promises和原生JS承諾可以安全地一起使用。
為什么這個異常會默默地消失?
謝謝。
除了引用答案中提供的技術原因外,供您考慮:
符合ES6 / A +標准的Promise實例共享:
then
是造成他們要執行已經運行完代碼后在自己的線程異步執行。 無論聽眾是否注冊了回叫,承諾都會得到解決(“履行”或“被拒絕”),
then
登記 throw
的值(使用throw
)用於拒絕then
注冊返回的promise,和 使用Promise實例解析的promise將自身與作為參數提供的最終已解決狀態和promise的值同步。 (在ES6標准中,這被描述為“鎖定”)。
不符合承諾的潛在特征包括對象
then
返回的promise。 Promise.resolve
可用於通過靜態值來解決其返回的promise,可能主要用於測試。 然而,它的主要目的是隔離不合規承諾的副作用。 Promise.resolve( thenable)
返回的承諾將展示上述1-7的所有行為,並且不會出現任何不符合行為的行為。
恕我直言我建議只在環境中使用非A + promise對象,並根據創建它們的庫的文檔。 非兼容的thenable可用於直接解析A + promise(這是Promise.resolve所做的),但是對於行為的完全可預測性,它應該在任何其他使用之前使用Promise.resolve( thenable)
包裝在Promise對象中。
注意我試圖測試Parse承諾的A +合規性,但它似乎沒有提供構造函數。 這使得“幾乎”或“完全”A +合規性的主張難以量化。 感謝zangw指出可能會將拒絕的promise作為一個偵聽器返回,作為拋出異常的替代方法。
為什么這個例外消失了?
Parse默認情況下不會捕獲異常,並且promises會吞下它們。
解析是不是100%的承諾/ A +兼容,但盡管如此它試圖吸收那些從返回thenables then
回調。 並且它既不捕獲異常也不異步執行自己的回調。
你在做什么,不能夠被復制then
使用
var p1 = new Parse.Promise();
var p2 = new Parse.Promise();
// p2 should eventually settle and call these:
p2._resolvedCallbacks = [function (res) { console.log("Success") }];
p2._rejectedCallbacks = [function (err) { console.log(err) }];
function handler() {
throw new Error("There was a failure");
}
// this is what the second `then` call sets up (much simplified):
p1._resolvedCallbacks = [function(result) {
p2.resolve(handler(result)); // throws - oops
}];
// the native promise:
var p = Promise.resolve();
// what happens when a callback result is assimilated:
if (isThenable(p))
p.then(function(result) {
p1.resolve(result);
});
問題是p1.resolve
是同步的,並立即在p1
上執行回調 - 這反過來會拋出。 通過在p2.resolve
調用之前p2.resolve
, p2
將永遠保持未決狀態。 例外冒泡並變成完成p1.resolve()
-現在拋出在回調於天然then
方法。 本機promise實現捕獲異常並拒絕then
返回的promise,但是無處不在。
默默?
如果您的“本機”承諾實現支持未處理的拒絕警告,您應該能夠在被拒絕的承諾中看到異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.