[英]How can I catch asynchronous-non-promised errors ? ( react to that specific error)
我知道那里有答案,但是我沒有找到實際問題的具體答案。
目前,我經常使用以下模式:
class A
{
getLocation()
{
return Promise.reject(2222222)
}
async a()
{
try
{
var loc = await this.getLocation();
alert(loc)
}
catch (e)
{
alert("catch 2")
}
}
}
new A().a();
- 結果:“捕獲2”
事件:如果我在getLocation
拋出錯誤:
getLocation()
{
throw Error("ffffff")
}
-我得到相同的結果-可以。
那么問題出在哪里呢?
眾所周知, asynchronously-non-promised
引發的錯誤是另一種野獸:
因此, 此代碼完全不會被捕獲 :
getLocation() //bad code from a third party code , third party code
{
return new Promise((v, x) => setTimeout(() =>
{
throw Error("ffffff")
}, 100))
}
題 :
關於我要捕獲錯誤的事實-是否有更好的捕獲方式?
當然可以:
window.onerror = function () { alert(4)}
但是,這將是沒有順序的流.catch(...)
或catch(){}
我將無法做到與導致錯誤的具體行動措施。
全面披露:
沒有現實生活中的場景。 學習目的。
異步拋出的錯誤不是野獸
是。 並且必須不惜一切代價避免這種情況。 因此, 切勿將業務代碼(包括瑣碎的事情,如屬性訪問)放在異步的非承諾回調中。 它可能會拋出! 顯而易見, JSON.parse
可能會失敗,當“對象”為null
或undefined
或涉及到吸氣劑時,屬性訪問可能會拋出,或者當原本應該為數組的事物沒有時,循環可能會失敗.length
。
允許作為異步非承諾回調的唯一事物是resolve
, reject
和(err, res) => { if (err) reject(err); else resolve(res); }
(err, res) => { if (err) reject(err); else resolve(res); }
(err, res) => { if (err) reject(err); else resolve(res); }
(也許是帶有多個參數的怪異API的可變版本)。
因此,將錯誤代碼重寫為
async getLocation() {
await new Promise(resolve => setTimeout(resolve, 100));
throw Error("ffffff");
}
要么
getLocation() {
return new Promise(resolve => setTimeout(resolve, 100)).then(res => {
throw Error("ffffff");
});
}
並且當第三方代碼讓他們修復時,向您的修復程序發出上游合並請求,或者如果那些無效則放棄該第三方。
是否有更好的模式來捕捉這一點?
好吧, 域 (在節點中)應該解決異步(未捕獲)異常的非局部性問題,但是它們沒有解決 。 也許有一天, 區提供更好的本地語言支持將取代他們。
錯誤應在發生錯誤的地方捕獲。
這種代碼是不正確的,應就地固定:
getLocation() //bad code from a third party code
{
return new Promise((v, x) => setTimeout(() =>
{
throw Error("ffffff")
}, 100))
}
如果這是第三方代碼,則可以對其進行分叉或修補。
正如已經提到的問題,可以通過onerror
全局跟蹤異常。 僅應將其用於通知開發人員現有錯誤,而不能以常規方式處理它們。
unhandledrejection
事件可用於相同目的,以通知諾言中未處理的拒絕。 它無法處理上面摘錄的錯誤,因為它被拋出到setTimeout
回調中,並且不會導致Promise拒絕。
我猜基本用法是這樣的:
class A { getLocation(x) { return new Promise((resolve, reject) => setTimeout(() => { // a lot of async code try { //simulate unexpected exception if (x === 2) { throw ("code error"); } if (x) { resolve('success'); } else { reject('conditional rejection'); } } catch (ex) { reject(ex); } }, 1000)); } async a(x) { await this.getLocation(x).then((loc) => console.info(loc)).catch((e) => console.error(e)); } } let o = new A(); oa(2); oa(0); oa(1);
拒絕Promise
不一定是代碼Exception
,而代碼Exception
也不一定會觸發Promise
拒絕。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.