當前位置:
首頁 > 知識 > 你是否也在學習ES6 Promise時遇到過這個問題?

你是否也在學習ES6 Promise時遇到過這個問題?

背景

周末閑來無事,隨便翻看了一下阮一峰老師的《ES6 標準入門》第2版,ps:之前在阮一峰老師的官網看過電子版,感覺乾貨滿滿,所以就買了紙質版;當看到第16章第4節 "Promise.prototype.catch"時,遇到了一個小困惑,下面我們來一起看一下

開胃湯

首先,Promise.prototype.catch方法是用來"捕獲Promise回調函數中自然發生或主動拋出的錯誤",何為自然發生?何為主動拋出?

自然發生的錯誤:

1 function a {
2 var x = 1;
3 console.log(x+y)
4 }
5
6 a // "ReferenceError: y is not defined"

變數y未定義,所以運行時產生了錯誤,這就是自然發生的錯誤,我們沒有做異常處理,即try catch

主動拋出的錯誤:

1 function a {
2 var x = 1;
3 try{
4 console.log(x+y)
5 }catch(err){
6 console.log(err)
7 }
8 }
9
10 a // "ReferenceError: y is not defined"

意識到可能會有異常出現,我們就用try catch處理,那我們如何區分一個錯誤是否被捕獲到了呢?很簡單,就是看瀏覽器控制台的日誌:

未捕獲到的錯誤日誌是紅色的

你是否也在學習ES6 Promise時遇到過這個問題?

捕獲到的錯誤日誌是黑色的

你是否也在學習ES6 Promise時遇到過這個問題?

正餐

上面已經說了Promise.prototype.catch的作用,以及錯誤的相關知識,那麼我究竟遇到了什麼問題呢?咱們繼續往下看

書上有這麼一個示例:

1 var promise = new Promise(function(resolve, reject){
2 throw new Error("test")
3 })
4 promise.catch(function(error){
5 console.log(error)
6 })
7 // Error: test

那我們就手動實踐一下吧

你是否也在學習ES6 Promise時遇到過這個問題?

錯誤真的被捕獲到了,歐耶,perfect!!突然我又想到Promise不是用來實現非同步操作的嗎?那我們就試試ajax吧,然後又意識到沒有介面(主要是當時懶得找),那就用SetTimeout代替吧

代碼:

1 new Promise(function (resolve, reject) {
2
3 // 非同步方式拋出異常
4 setTimeout(function {
5 throw new Error("出錯1")
6 },2000)
7
8 // 同步方式拋出異常
9 throw new Error("出錯2")
10 }).catch(function (err) {
11 console.log(err)
12 })

運行截圖:

你是否也在學習ES6 Promise時遇到過這個問題?

納尼?!錯誤1沒有被捕獲?開玩笑呢,讓我緩一緩,終於想到了:setTimeout是在Window下執行的,記得不?上面的代碼就相當於:

1 var clock = function {
2 setTimeout(function {
3 throw new Error("出錯1")
4 })
5 }
6
7 new Promise(function (resolve, reject) {
8
9 // 非同步方式拋出異常
10 clock
11
12 // 同步方式拋出異常
13 throw new Error("出錯2")
14 }).catch(function (err) {
15 console.log(err)
16 })

當我們執行一個函數時,歸根到底就是把函數體內代碼拿到它被調用的地方執行;所以在上上個示例中,在Promise實例中只是啟動了setTimeout定時器,之後定時器就和Promise實例完全沒有關係了,因為它被交由Window對象了,所以定時器中拋出的異常沒有想我們想像的被Promise示例捕獲,而是未加處理,直接在控制台報錯;怎麼樣?你是否已經理解,如果理解了,我們再鞏固一下,看看下面的代碼:

1 var clock = function {
2 setTimeout(function {
3 console.log(this === window)
4 throw new Error("出錯1")
5 })
6 }
7
8 var func = function {
9 throw new Error("出錯3")
10 }
11
12
13 new Promise(function (resolve, reject) {
14 // 非同步方式拋出異常
15 clock
16
17 // 執行window.func拋出異常
18 func
19
20 // 同步方式拋出異常
21 throw new Error("出錯2")
22 }).catch(function (err) {
23 console.log(err)
24 })

這裡錯誤3能不能被catch捕獲呢?答案是:Yes

你是否也在學習ES6 Promise時遇到過這個問題?

不要被迷惑呦!雖然func是在Promise示例外面定義的,但是它和錯誤2是拋出方式沒兩樣兒

結語

這就是我在學習Promise相關知識時遇到的一個小插曲,我不相信只有我一個人有這個經歷,哈哈;關於Promise的其他知識這裡不是沒有介紹,而是絲毫沒有介紹,不好意思,我又調皮了,主要是我覺得學習ES6,看阮一峰老師的《ECMAScript 6 入門》就夠了,好了,就到這裡吧,祝大家周末愉快!!

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 達人科技 的精彩文章:

如何在require中使用VUE
GPUImage的filter 響應處理鏈 的理解筆記
高並發環境下,Redisson實現redis分布式鎖

TAG:達人科技 |

您可能感興趣

現在這個時候,是否適合買iPhone X了?
Google獨立站SEO,這些點,你是否做到?
iPhone 5s是否能升級iOS 12系統?對!有這個可能性
這雙女生專屬的Nike WMNS Air More Uptempo是否讓你羨慕不已?
如此前衛的設計你是否會買帳?Vetements x Reebok
不確定Public School x Nike Air Force 1限量50雙是否發售?近賞完再說!
你是否曾仰望星空,想像過宇宙的樣子?讀《時間簡史》A Brief History of Time 001
Joaquin Phoenix就是否出演小丑而在洽談中
FAQ詳解「Meltdown和Spectre」問題,接踵而來的「Skyfall和Solace」是否僅是騙局?
現在你可以檢查你的 Facebook 信息是否與 Cambridge Analytica 共享
Chrome OS是否會被取代?Pixelbook成功啟動Win10
ios系統更新,決定了你的iPhone6s是否有力再戰!
Kanye West 的失常,是否是一場 「陰謀? | K-WORD
Kanye West 的失常,是否是一場 「陰謀?
微軟是否有意徹底淘汰Windows Media Player?
喜歡咖喱的你是否對這雙Nike Air Max 1一見鍾情呢?
新iPad Pro將近,是否如我們願想
你們的iPhone x使用多長時間了 是否有燒屏現象?
跑分相差一萬分 有了iPhoneX是否拋棄iPhone4
現在入手iPhone 8是否划算?