Promsie
通俗來說,Promise就是一個(gè)承諾,例如,我承諾明年要賺1百萬,then方法中的onFulfilled就是承諾完成后要做的事,onRejected就是承諾失敗要做的事情,而Promise構(gòu)造函數(shù)中的resolve用來手動完成這個(gè)承諾,reject用來手動讓承諾失敗
overview
-
構(gòu)造函數(shù)
new Promise((resolve, reject) => {}) -
實(shí)例方法(原型對象上的方法)
Promise.prototype.then(onFulfilled, onRejected) Promise.prototype.catch(onRejected) -
靜態(tài)方法
Promise.all() Promsie.race() Promsie.resolve() Promsie.reject() -
狀態(tài)
- pedding(因?yàn)槭窃诘却隣顟B(tài)的改變,所以是ing)
- fulfilled(因?yàn)槭莝etted,表示已經(jīng)完成的,所以需要ed)
- rejected(因?yàn)槭莝etted,表示已經(jīng)完成的,所以需要ed)
構(gòu)造函數(shù)
new Promise((resolve, reject) => {
resolve(val)
})
-
接受的參數(shù)
接受的參數(shù)是一個(gè)function,成為executor,promise會往這個(gè)executor注入兩個(gè)函數(shù)作為參數(shù)
- resolve 當(dāng)調(diào)用resolve,表示的是把Promise的狀態(tài)從pedding變成fulfilled,那么接下去就會執(zhí)行then中注冊的onFulfilled方法 - reject 當(dāng)調(diào)用reject,表示的是把Promise的狀態(tài)從pedding變成rejected,那么接下去就會執(zhí)行then中注冊的onRejected方法 -
返回的結(jié)果
返回的是一個(gè)promise實(shí)例,狀態(tài)是pedding
實(shí)例方法(原型對象上的方法)
-
then
then方法接受兩個(gè)參數(shù),onFulfilled和onRejected,返回的是一個(gè)新的Promise實(shí)例,例如:
const p = new Promise() p.then(val => val) // 如果p的狀態(tài)是fulfilled,相當(dāng)于 Promise.resove(val)此時(shí)的then返回的是一個(gè)新的promise對象,如果p的狀態(tài)是fulfilled,那么then的onFulfilled函數(shù)
val => val就會被執(zhí)行,然后返回一個(gè)狀態(tài)是fulfilled的promise對象,相當(dāng)于Promise.resolve(val),這也是then鏈?zhǔn)秸{(diào)用的關(guān)鍵 -
catch
說到catch,就要說到promise中的錯誤處理情況,promise內(nèi)部會捕獲錯誤,主要有三種情形:
``` // 寫法一 var promise = new Promise(function(resolve, reject) { try { throw new Error('test'); } catch(e) { reject(e); } }); promise.catch(function(error) { console.log(error); }); // 寫法二 var promise = new Promise(function(resolve, reject) { reject(new Error('test')); }); promise.catch(function(error) { console.log(error); }); ``` 1. 同步的錯誤,在promise發(fā)生的錯誤會被promise捕獲,但是不會有反應(yīng),因?yàn)殄e誤沒有被處理,但是在chrome中會拋錯 ``` new Promise((resolve, reject) => { throw new Error() // 不會有反應(yīng),因?yàn)閑rror被捕獲但是沒有被處理,chrome的實(shí)現(xiàn)不同 }) ``` 2. 異步的錯誤,異步發(fā)生的錯誤不在當(dāng)前的callstack,當(dāng)前同步的代碼已經(jīng)執(zhí)行完,沒有發(fā)現(xiàn)錯誤,所以異步的錯誤無法捕獲,會拋錯 ``` new Promise((resolve, reject) => { setTimeout(() => { throw new Error() }, 0) }) ``` 3. 使用reject捕獲錯誤,無論異步還是同步的都能捕獲,然后交給catch處理,注意錯誤是會冒泡,所以一般在最后使用catch捕獲錯誤
靜態(tài)方法
-
Promise.resolve()
接受的參數(shù)有三種情況:
1. value 返回一個(gè)狀態(tài)為fulfilled的promise對象,value是傳遞給onFulfilled的參數(shù) 2. promise Promise.resolve(promise)返回的實(shí)例會"follow"promise的狀態(tài) ``` const p1 = new Promise((resolve, reject) => { setTimeout(() => resolve('hello'), 1000) }) const p2 = new Promise((resolve, reject) => { resolve(p1) }) p2.then(val => console.log(val, 2)) p1.then(val => { console.log(p1) console.log(p2) console.log(val, 1) }) ``` 結(jié)果:過1s后,先打印出p1,是一個(gè)promise對象,狀態(tài)是resolved,然后打印p2,狀態(tài)是pedding,然后打印hello,1,然后打印hello,2 有這樣的結(jié)果是因?yàn)?,傳遞給p2的resove的參數(shù)是一個(gè)promise,p1,那么p2就會"follow"p1的狀態(tài),但當(dāng)p1的狀態(tài)改變后,p2的狀態(tài)才會改變,而且會先執(zhí)行掛載在p1上回調(diào),然后再執(zhí)行掛載在p2上的回調(diào)函數(shù) 3. thenable 在MDN中對Promise.resolve中的介紹中說到,如果參數(shù)是一個(gè)thenable的對象,也就是擁有then方法的對象,那么Promise.resolve(thanable)返回的Promise實(shí)例會"follow"這個(gè)thenable對象的狀態(tài),簡單的來說,就是跟隨thenable對象狀態(tài)的改變而改變 ``` var p = Promise.resolve({ then: (onFulfilled, onRejected) => { setTimeout(onRejected, 1000, new Error()) set } }) p.then(val => console.log(val)).catch(error => console.log(error)) ``` 當(dāng)then中的onFulfilled方法被調(diào)用的時(shí)候,表示之前的promise實(shí)例的狀態(tài)是fulfilled,所以then會返回一個(gè)新的promise實(shí)例,狀態(tài)是fulfilled,相當(dāng)于Promise.resolve(val)