2015-10-16 103 views
1

當我的Promise定義中的某個異步調用引發錯誤時,我似乎無法將其傳播給我的catch處理程序。在JavaScript Promise中引發異步失敗

var promise = new Promise(function(resolve, reject) { 
    setTimeout(function() { 
     console.log('about to fail!'); 
     throw new Error('async FAIL'); 
    }, 1000) 

    throw new Error('synchronous fail!'); 
}).catch(function(err) { 
    console.log('catch1!!!'); 
    throw err; 
}); 

promise.catch(function(err) { 
    console.log('CAUGHT!'); 
    console.log(err.stack); 
}); 

此代碼有效捕獲同步故障。但是,有沒有什麼方法可以在Promise rubric中捕捉異步故障?我是否缺少一些關於如何使用承諾的基礎知識?

+0

你爲什麼不使用拒絕? – Saar

+0

好吧,這個想法是,其他一些電話會導致失敗(不是我明確的投擲)。所以,我真的不想把整個街區都封閉起來,試圖解決任何可能出錯的電話...... –

+1

你不能那樣做。 「但是,有什麼方法可以在Promise rubric內找到異步失敗?」 ---不,它不會從那裏彈出,因爲它不屬於當前的調用堆棧。 – zerkms

回答

0

您不能捕獲與承諾異步拋出的異常 - 或者除了全局平臺錯誤處理程序以外的任何其他方式。承諾當然不是魔術。

這就是爲什麼您必須在最低級別執行promisification - 因爲承諾處理程序隱式地打電話try/catch

0

如果異步代碼具有成功/失敗回調函數,則可能出現閉包。問題是保持參照決心/拒絕功能在不同的調用堆棧:

function mySuccessCallback(resolve) { 
    return function() { 
     resolve(); 
    }; 
} 
function myFailureCallback(reject) { 
    return function() { 
     reject(); 
    }; 
} 
var promise = new Promise(function(resolve, reject) { 
    var thirdPartyTool = new ThirdPartyTool(); 
    thirdPartyTool.executeAsync(
     mySuccessCallback(resolve), 
     myFailureCallback(reject)); 
}); 

如果沒有成功/失敗回調那麼如何才能代碼可能知道什麼時候他們已經完成異步操作?除非當然你的promise對象只承諾異步調用將被執行,只不過是異步操作完成時無關緊要。但唯一可以判斷是否有其他代碼拋出了異常的唯一方法是使用全局錯誤處理程序(https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror),因爲另一個人說它在一個完全不同的調用堆棧中冒泡。但即使如此,你怎麼能一般保證被捕獲的錯誤是由該特定的異步調用而不是另一個?