Promise 小結(jié)
Promise 的生命周期
每個Promise都有自己的一個生命周期,開始未處理然后變成已處理。開始pedding狀態(tài)表示進行中,操作結(jié)束后。Promise可能進入以下兩種狀態(tài)某一個:
Fuiflled Promise操作完成。 Rejected 程序錯誤或者其他原因Promise為可以完成。

內(nèi)部[[PromiseState]]用來表示三個狀態(tài):pending,fulfilled及rejected。這個屬性并沒有暴露在Promise對象上,所以檢測不到。Promise狀態(tài)改變的時候通過then獲得。 所有Promise都有then方法,兩個參數(shù):第一個是Promise的狀態(tài)變?yōu)閒ulfilled時候調(diào)用的函數(shù),與異步操作有關(guān)數(shù)據(jù)傳遞給這個參數(shù)。第二個是變?yōu)閞ejected時執(zhí)行的函數(shù),失敗相關(guān)附加數(shù)據(jù)可以通過參數(shù)傳遞給這個拒絕函數(shù)。
Tips 注意new Promise的時候傳遞函數(shù)會立即執(zhí)行并且函數(shù)體內(nèi)的操作是一個同步操作。
new Promise((res,rej) =>{}),接收一個函數(shù)作為參數(shù),函數(shù)有兩個參數(shù)是兩個callback表示成功和失敗的時候執(zhí)行的。
????let?p?=?new?Promise((res,rej)?=>?{
????????console.log(1,'1')
????????res("success")
????????console.log(2,'2')
????})
????p.then((resolve)=>{
????????console.log(resolve,'resolve')
????},(reject)=>?{
????????console.log(reject,'reject')
????})
????console.log(4)
????//?輸出順序?1?2?4?success
Promise 鏈的返回值
Promise鏈的一個重要特性就是可以給下游Promise傳遞數(shù)據(jù),如果在完成處理程序中指定一個返回值,則可以沿著這條鏈繼續(xù)傳遞數(shù)據(jù)。
Tips: Promise鏈中的返回值如果是Promise對象的話根據(jù)返回的Promise狀態(tài)進行執(zhí)行對應then和catch,如果return一個非Promise那么會把它使用Promise.resolve包裝成為一個fulfilled狀態(tài)的Promise。 如果then中沒有return值,那就相當于return一個空的Promise對象(已完成狀態(tài))。比如:
let?a?=?new?Promise((res,rej)?=>?{
????res(6)
})
a.then((res)?=>?{
????console.log(res,'第一個執(zhí)行完成')
????//?6
}).then(res=>?{
????console.log("第二個返回打印",res)
????//?第二個返回打印?undefined
})
鏈式調(diào)用Promise:
let?p1?=?new?Promise(function?(resolve,reject)?{
????resolve(42)
})
p1.then(function(value)?{
????console.log(value)
????//?return一個常量?then中的return會自動包裝為Promise.resolve(xx)
????return?value+1
}).then((res)?=>?{
????console.log(res)?//?43
})
//?拒絕處理程序中是同樣的
let?p1?=?new?Promise((reslove,reject)?=>?{
????reject(42)
})
p1.catch((rej)?=>?{
????console.log(rej)
????return?rej+1?//?return非Promise對象,使用Promise.resolve包裝
}).then((value)?=>?{
????console.log(value)?//43
})
Promise 錯誤解決方案
Promise的錯誤捕捉有兩種方式
then函數(shù)的第二個參數(shù)。
let?a?=?new?Promise((res,rej)?=>?{
????rej(2)
})
a.then(?(res)?=>?{
????//?success?do
},(rej)?=>?{
????//?reject?do
????console.log(2)?//?2
})
catch函數(shù)
let?a?=?new?Promise((res,rej)?=>?{
????rej(2)
})
a.then(res?=>?{
????//?success?do
}).catch(err?=>?{
????//?do?sth
})
catch函數(shù)可以在鏈式調(diào)用的時候當作整個鏈的Promise錯誤處理程序。
a.then(res=>?{
????
}).then(res=>?{
????
}).then((res)?=>?{
????
}).catch(rej?=>?{
????//?任意一個環(huán)節(jié)走到錯誤都會走到.catch這里
????//?并且無return中斷環(huán)節(jié)的執(zhí)行(因為已經(jīng)catch失敗,第一個then就調(diào)用不到了,所以鏈式結(jié)束)。
})
Promise 的繼承
Promise類和其他內(nèi)建類型一致,也可以作為基類派生類,所以也可以定義自己的Promise變量來擴展Promise的功能。
class?MyPromise?extends?Promise?{
????//?使用默認的Promise構(gòu)造函數(shù)
????success(resolve,reject)?{
????????return?this.then(reslove,reject)
????}
????failure(reject)?{
????????return?this.catch(reject)
????}
}
let?promise?=?new?MyPromise(function?(resolve,reject)?{
????resolve(42)
})
promise.success(function(value)?{
????console.log(value)
},function(value)?{
????console.log(value)
})
//?or
promise.failure(function?(value)?{
????console.log(value)
})
這個例子中擴展了兩個success和failure方法。這兩個方法都通過this調(diào)用它模仿的方法,派生Promise與內(nèi)建Promise功能一致,只不過多了success和failure這兩個可以調(diào)用的方法。 用于靜態(tài)方法會也會被繼承,因此派生的Promise也都存在MyPromise.resolve(),MyPromise.reject(),MyPromise.all(),MyPromise.race()靜態(tài)方法。
后兩者與內(nèi)建方法完全不同,前兩個稍有不同。

評論
圖片
表情
