国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

警示后人系列:為什么我沒(méi)有catch到回調(diào)函數(shù)中拋出的錯(cuò)誤?

fnngj / 947人閱讀

摘要:回調(diào)函數(shù)的棧幀被放入時(shí),執(zhí)行棧是空的。總結(jié)用語(yǔ)句包裹回調(diào)函數(shù)的定義,無(wú)法捕獲到回調(diào)函數(shù)中的錯(cuò)誤。如果回調(diào)函數(shù)運(yùn)行時(shí)沒(méi)有外層函數(shù),你必須在回調(diào)函數(shù)內(nèi)部做錯(cuò)誤的捕獲和處理。

今天犯了一個(gè)js中的錯(cuò)誤,記錄一下警示后人:)

事情是這樣,koa會(huì)幫我們捕獲中間件中拋出的錯(cuò)誤,從而不讓服務(wù)器崩潰,如下圖:

服務(wù)器為此次請(qǐng)求返回500,仍然能夠處理后續(xù)的請(qǐng)求。

從這一點(diǎn)出發(fā),我就認(rèn)為,我可以在中間件里面隨便throw,這樣koa就能在控制臺(tái)幫我打印出所有錯(cuò)誤的信息,反正也不會(huì)對(duì)后續(xù)請(qǐng)求造成影響。

但是今天的錯(cuò)誤是這樣的:

進(jìn)程居然崩潰了!這樣上線豈不是要出事?

為什么koa這回沒(méi)有捕獲到我throw的錯(cuò)誤呢?

用簡(jiǎn)單的代碼模擬一下這個(gè)場(chǎng)景:

try {
  setTimeout(() => {
    try {
      throw 500;
    } catch (err) {
      console.log("err1", err);  // called
      throw err;
    }
  }, 0);
} catch (err) {
  console.log("err2", err)  // never called
}


可以看出,內(nèi)層的try確實(shí)捕獲到了錯(cuò)誤,但是當(dāng)我們把這個(gè)錯(cuò)誤繼續(xù)拋出,外層的try卻沒(méi)有捕獲到這個(gè)錯(cuò)誤

原因在于,回調(diào)函數(shù)被異步調(diào)用時(shí),外層try中的代碼其實(shí)已經(jīng)執(zhí)行完了,棧幀已經(jīng)從執(zhí)行棧中彈出。回調(diào)函數(shù)的棧幀被放入時(shí),執(zhí)行棧是空的

錯(cuò)誤被拋出后,沿著執(zhí)行棧,希望找到“外層”函數(shù)的try...catch語(yǔ)句。可是這個(gè)回調(diào)函數(shù)根本就沒(méi)有“外層”函數(shù)了,因此這是一個(gè)沒(méi)有被捕獲到的錯(cuò)誤,這會(huì)造成進(jìn)程的崩潰。

總結(jié)

用try語(yǔ)句包裹回調(diào)函數(shù)的定義,無(wú)法捕獲到回調(diào)函數(shù)中的錯(cuò)誤。必須用try語(yǔ)句包裹運(yùn)行時(shí)的外層函數(shù)。如果回調(diào)函數(shù)運(yùn)行時(shí)沒(méi)有外層函數(shù),你必須在回調(diào)函數(shù)內(nèi)部做錯(cuò)誤的捕獲和處理。

如果回調(diào)函數(shù)定義在Promise中,你可以直接在回調(diào)函數(shù)中調(diào)用reject(reason),讓這個(gè)Promise的訂閱者來(lái)處理錯(cuò)誤:

const p = new Promise((resolve, reject) => {
  setTimeout(() => {
    try {
      throw 500;
    } catch (err) {
      console.log("err1", err);  // called
      reject(err);
    }
  }, 0);
});

p.catch(err => {
  console.log("err3", err);  // called
});

如果回調(diào)函數(shù)由async function的await關(guān)鍵字來(lái)執(zhí)行,那么可以通過(guò)reject Promise,讓async function中的try...catch捕獲到錯(cuò)誤。

async function fun() {
  try {
    await new Promise((resolve, reject) => {
      setTimeout(() => {
        try {
          throw 500;
        } catch (err) {
          console.log("err1", err);  // called
          reject(err);
        }
      }, 0);
    });
  } catch (err) {
    console.log("err4", err);  // called
    throw err;
  }
}
try {
  fun();
} catch (err) {
  console.log("err5", err);  // not called
}

注意try {fun();}無(wú)法捕獲到錯(cuò)誤,因?yàn)檫@個(gè)函數(shù)不是通過(guò)await來(lái)執(zhí)行的。錯(cuò)誤拋出的時(shí)候,這個(gè)try語(yǔ)句早已經(jīng)執(zhí)行完。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/93302.html

相關(guān)文章

  • Node 錯(cuò)誤處理之挖坑系列

    摘要:一中的對(duì)象包含了錯(cuò)誤的具體信息,包括錯(cuò)誤堆棧等。不源碼了,特別簡(jiǎn)單,自己去一下。 一. Error ????JS 中的 Error 對(duì)象. 包含了錯(cuò)誤的具體信息,包括 name、message、錯(cuò)誤堆棧 stack 等。可以以 new Error 方式創(chuàng)建實(shí)例拋出,或調(diào)用 Error.captureStackTrace 為已有對(duì)象添加 stack 錯(cuò)誤堆棧信息 而后拋出showImg(...

    afishhhhh 評(píng)論0 收藏0
  • 解析 Promise 原理,實(shí)現(xiàn)一個(gè)Promise

    摘要:解析原理,實(shí)現(xiàn)一個(gè)概述這篇文章旨在解析的異步實(shí)現(xiàn)原理,并且以中的為藍(lán)本實(shí)現(xiàn)一個(gè)簡(jiǎn)單的。具體的規(guī)范可以參見(jiàn)細(xì)節(jié)構(gòu)造器中必須傳入函數(shù),否則會(huì)拋出錯(cuò)誤。中的回調(diào)返回值會(huì)影響返回的對(duì)象。執(zhí)行器傳入構(gòu)造器的為函數(shù),并且在構(gòu)造時(shí)就會(huì)執(zhí)行。 解析 Promise 原理,實(shí)現(xiàn)一個(gè)Promise 概述 這篇文章旨在解析 Promise的異步實(shí)現(xiàn)原理,并且以 ES6中的 Promise 為藍(lán)本實(shí)現(xiàn)一個(gè)簡(jiǎn)單...

    silenceboy 評(píng)論0 收藏0
  • JavaScript的異常處理

    摘要:主要用于捕捉異常。這包括在塊里拋出的異常。并且同時(shí)捕獲到一些關(guān)于異常的信息。秒后輸出統(tǒng)一異常處理代碼中拋出的異常,一種是要展示給用戶,一種是展示給開(kāi)發(fā)者。 當(dāng) JavaScript 引擎執(zhí)行 JavaScript 代碼時(shí),有可能會(huì)發(fā)生各種異常,例如是語(yǔ)法異常,語(yǔ)言中缺少的功能,由于來(lái)自服務(wù)器或用戶的異常輸出而導(dǎo)致的異常。 而 Javascript 引擎是單線程的,因此一旦遇到異常,Ja...

    PrototypeZ 評(píng)論0 收藏0
  • 對(duì)JavaScript中的異步函數(shù)進(jìn)行異常處理及測(cè)試

    摘要:總結(jié)最后總結(jié)一下從異步函數(shù)拋出的錯(cuò)誤不會(huì)是普通的異常。異步函數(shù)和異步方法總是返回一個(gè),無(wú)論是已解決還是被拒絕。要攔截異步函數(shù)中的異常,必須使用。 翻譯:瘋狂的技術(shù)宅原文:https://www.valentinog.com/bl... 本文首發(fā)微信公眾號(hào):jingchengyideng歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章 可以在 Javascript 的異步函數(shù)中拋出錯(cuò)誤嗎...

    bigdevil_s 評(píng)論0 收藏0
  • 對(duì)JavaScript中的異步函數(shù)進(jìn)行異常處理及測(cè)試

    摘要:總結(jié)最后總結(jié)一下從異步函數(shù)拋出的錯(cuò)誤不會(huì)是普通的異常。異步函數(shù)和異步方法總是返回一個(gè),無(wú)論是已解決還是被拒絕。要攔截異步函數(shù)中的異常,必須使用。 翻譯:瘋狂的技術(shù)宅原文:https://www.valentinog.com/bl... 本文首發(fā)微信公眾號(hào):jingchengyideng歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章 可以在 Javascript 的異步函數(shù)中拋出錯(cuò)誤嗎...

    paulli3 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

fnngj

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<