周末閑來無(wú)事,隨便翻看了一下阮一峰老師的《ES6 標(biāo)準(zhǔn)入門》第2版,ps:之前在阮一峰老師的官網(wǎng)看過電子版,感覺干貨滿滿,所以就買了紙質(zhì)版;當(dāng)看到第16章第4節(jié) 'Promise.prototype.catch()'時(shí),遇到了一個(gè)小困惑,下面我們來一起看一下

 

開胃湯

首先,Promise.prototype.catch方法是用來'捕獲Promise回調(diào)函數(shù)中自然發(fā)生或主動(dòng)拋出的錯(cuò)誤',何為自然發(fā)生?何為主動(dòng)拋出?

自然發(fā)生的錯(cuò)誤:

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

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

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

變量y未定義,所以運(yùn)行時(shí)產(chǎn)生了錯(cuò)誤,這就是自然發(fā)生的錯(cuò)誤,我們沒有做異常處理,即try catch

主動(dòng)拋出的錯(cuò)誤:

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

 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'

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

意識(shí)到可能會(huì)有異常出現(xiàn),我們就用try catch處理,那我們?nèi)绾螀^(qū)分一個(gè)錯(cuò)誤是否被捕獲到了呢?很簡(jiǎn)單,就是看瀏覽器控制臺(tái)的日志:

未捕獲到的錯(cuò)誤日志是紅色的

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

捕獲到的錯(cuò)誤日志是黑色的

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

 

正餐

上面已經(jīng)說了Promise.prototype.catch的作用,以及錯(cuò)誤的相關(guān)知識(shí),那么我究竟遇到了什么問題呢?咱們繼續(xù)往下看

書上有這么一個(gè)示例:

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

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

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

那我們就手動(dòng)實(shí)踐一下吧

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

錯(cuò)誤真的被捕獲到了,歐耶,perfect??!突然我又想到Promise不是用來實(shí)現(xiàn)異步操作的嗎?那我們就試試ajax吧,然后又意識(shí)到?jīng)]有接口(主要是當(dāng)時(shí)懶得找),那就用SetTimeout代替吧

代碼:

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

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

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

運(yùn)行截圖:

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

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

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

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

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

當(dāng)我們執(zhí)行一個(gè)函數(shù)時(shí),歸根到底就是把函數(shù)體內(nèi)代碼拿到它被調(diào)用的地方執(zhí)行;所以在上上個(gè)示例中,在Promise實(shí)例中只是啟動(dòng)了setTimeout定時(shí)器,之后定時(shí)器就和Promise實(shí)例完全沒有關(guān)系了,因?yàn)樗唤挥蒞indow對(duì)象了,所以定時(shí)器中拋出的異常沒有想我們想象的被Promise示例捕獲,而是未加處理,直接在控制臺(tái)報(bào)錯(cuò);怎么樣?你是否已經(jīng)理解,如果理解了,我們?cè)凫柟桃幌?,看看下面的代碼:

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

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

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

這里錯(cuò)誤3能不能被catch捕獲呢?答案是:Yes

Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

不要被迷惑呦!雖然func是在Promise示例外面定義的,但是它和錯(cuò)誤2是拋出方式?jīng)]兩樣兒

 

結(jié)語(yǔ)

這就是我在學(xué)習(xí)Promise相關(guān)知識(shí)時(shí)遇到的一個(gè)小插曲,我不相信只有我一個(gè)人有這個(gè)經(jīng)歷,哈哈;關(guān)于Promise的其他知識(shí)這里不是沒有介紹,而是絲毫沒有介紹,不好意思,我又調(diào)皮了,主要是我覺得學(xué)習(xí)ES6,看阮一峰老師的《ECMAScript 6 入門》就夠了,好了,就到這里吧,祝大家周末愉快??!

http://www.cnblogs.com/sampapa/p/6979260.html