簡體   English   中英

如何捕獲異步非承諾錯誤? (對此特定錯誤做出反應)

[英]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可能會失敗,當“對象”為nullundefined或涉及到吸氣劑時,屬性訪問可能會拋出,或者當原本應該為數組的事物沒有時,循環可能會失敗.length

允許作為異步非承諾回調的唯一事物是resolvereject(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM