成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

try...catch 抓不到 Promise 的錯誤?原來是這么回事

開發
在 JavaScript 中,try...catch 是我們處理錯誤的得力助手。但當你開始和 Promise 打交道時,可能會遇到一個讓你困惑的場景。

在 JavaScript 中,try...catch 是我們處理錯誤的得力助手。我們很自然地認為,只要把可能出錯的代碼放進 try 塊,catch 就一定能捕獲到異常。但當你開始和 Promise 打交道時,可能會遇到一個讓你困惑的場景:

try {
 // 假設這是一個會失敗的 API 請求
 fetch('https://non-existent-url.com/api'); 
 console.log('請求已發送');
} catch (error) {
 // 這里的 catch 會執行嗎?
 console.log('抓到錯誤了!', error);
}

// 控制臺輸出:
// 請求已發送
// Uncaught (in promise) TypeError: Failed to fetch

咦?catch 塊根本沒有執行!錯誤信息直接在控制臺炸開了,帶著一個扎眼的 Uncaught (in promise)。

這究竟是為什么?難道 try...catch 對 Promise 無效嗎?

別急,這并非 try...catch 的 bug,而是我們對 同步 與 異步 的理解出了偏差。

核心原因:try...catch 是同步的,而 Promise 是異步的

讓我們用一個更簡單的比喻來理解:

你點了一份外賣(發起一個 Promise 請求)。try...catch 就像你家門口的保安。

  • 你下單的動作是瞬間完成的。你按下“支付”按鈕,App 立刻告訴你“下單成功,騎手正在路上”。這個“下單成功”的反饋是 同步 的。
  • 保安 try...catch 只在你下單的那個瞬間盯著你。他看到你成功下了單,沒出任何問題(比如網絡斷了、余額不足等),于是他就下班了。
  • 半小時后,騎手送餐路上翻車了(Promise 狀態變為 rejected)。這個錯誤發生在未來,發生在保安下班之后。保安自然是抓不到這個“錯誤”的。

回到代碼中:

  • try { ... } 塊里的代碼是 同步執行 的。
  • fetch(...) 這個函數被調用時,它 立即返回 一個 Promise 對象。在 try 塊看來,這個返回動作是成功的,沒有任何錯誤被“拋出”(throw)。
  • 所以,try 塊順利執行完畢,catch 自然不會被觸發。
  • 真正的網絡錯誤發生在稍后的某個時間點,當這個錯誤發生時,它改變了那個已經返回的 Promise 對象的狀態,將其置為 rejected。這個錯誤屬于 異步世界,而同步的 try...catch早已執行完畢,鞭長莫及。

正確的姿勢:使用 async/await

那么,如何讓保安(try...catch)等到外賣送到(或出事)再下班呢?答案就是使用 async/await。

await 關鍵字有一個神奇的魔力:它會“暫停”當前 async 函數的執行,直到它等待的 Promise 有了結果(無論是成功 resolved 還是失敗 rejected)。

如果 Promise 失敗了,await 會像一個“信使”,把這個異步的錯誤“解包”并 重新在當前同步上下文中拋出。這樣一來,try...catch 就能穩穩地接住它了。

讓我們來改造一下代碼:

看,這次 catch 完美地捕獲了錯誤!

async/await 的工作流程:

  • 函數用 async 標記,表示這是一個異步函數。
  • await 守在 fetch(...) 前面,函數執行到這里就“暫停”了,但不會阻塞整個程序。
  • 它耐心等待 fetch 返回的 Promise 結果。
  • 當 Promise 因為網絡問題而 rejected 時,await 將這個 rejection 的原因(也就是那個 error 對象)作為一個同步錯誤 throw 出來。
  • 這個被 throw 出來的錯誤,正好在 try 塊的作用域內,于是被 catch 成功捕獲。

別忘了還有 .catch() 方法

當然,處理 Promise 錯誤并非只有 async/await 這一條路。在 async/await 出現之前,我們一直使用 Promise 自帶的 .catch() 方法鏈式調用來處理錯誤,這同樣非常有效。

fetch('https://non-existent-url.com/api')
  .then(response => {
    if (!response.ok) {
      // 手動拋出一個錯誤,讓下面的 .catch() 捕獲
      throw new Error('網絡響應不佳');
    }
    return response.json();
  })
  .then(data => {
    console.log('請求成功:', data);
  })
  .catch(error => {
    // 任何在 .then() 鏈中發生的錯誤都會在這里被捕獲
    console.log('在 .catch() 方法中抓到錯誤了!', error);
  });

這種方式的優點是代碼結構清晰,形成了一條“成功路徑” (.then) 和一條“失敗路徑” (.catch)。

責任編輯:趙寧寧 來源: JavaScript
相關推薦

2020-06-30 08:12:32

VMwareKVMDocker

2022-08-15 08:01:00

三色標記JVM算法

2021-07-29 16:56:59

微信騰訊注冊

2025-04-03 10:39:56

2022-10-21 08:17:13

MongoDB查詢Document

2018-06-04 08:40:20

磁盤分區MBR

2021-02-07 08:13:18

@DateTimeFo@NumberFormSpring

2020-03-04 08:47:10

Kafka架構原理

2020-02-23 15:55:00

疫情AI人工智能

2020-11-12 07:32:53

JavaScript

2022-01-14 14:19:38

ReactTS前端

2012-01-11 09:15:45

Objective-C

2025-06-25 08:15:00

JavaScrip異步編程代碼

2020-09-27 07:48:40

不用try catch

2024-10-11 11:59:03

2017-06-06 15:13:07

2022-12-14 07:32:40

InnoDBMySQL引擎

2023-09-07 07:53:21

JavaScriptGoRust

2023-04-09 23:25:30

Java注解元注解

2018-04-02 15:13:21

網絡
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 嫩草伊人 | 老司机深夜福利网站 | 国产大片一区 | 狠狠操狠狠 | 一呦二呦三呦国产精品 | 欧美在线天堂 | 天天操天天干天天曰 | 成人午夜激情 | 99国产精品一区二区三区 | 成人精品福利 | 日韩二| 日韩精品1区2区3区 爱爱综合网 | 天天躁日日躁狠狠很躁 | 久久久青草婷婷精品综合日韩 | 亚洲综合日韩精品欧美综合区 | 成人 在线 | 亚洲精品一区在线 | 国产精品视频久久久 | 久久亚洲一区二区 | 97视频在线观看免费 | 欧美二区在线 | 一区二区三区国产精品 | 日韩成人免费在线视频 | 久久高清 | 精品一区二区在线观看 | 精品三区| 91精品久久久久 | 欧美精品一区在线 | 精品99爱视频在线观看 | 中文字幕在线视频免费视频 | 人人玩人人添人人澡欧美 | 欧美激情综合色综合啪啪五月 | 日韩在线看片 | 欧美男人天堂 | 亚洲精品一区在线观看 | 成人免费一区二区三区视频网站 | 99久久久久 | 国产精品久久久久久福利一牛影视 | 精品乱码一区二区三四区视频 | 欧美黄色精品 | 亚洲经典一区 |