【ES6(2015)】Promise
文章目錄
- 1. 異步操作
- 2. Promise 基本語法
- 3. Promise.prototype.then()
- 4. Promise.prototype.catch()
- 5. Promise.resolve()
- 6. Promise.reject()
- 7. Promise.all()
- 8. Promise.race()
1. 異步操作
JS是單線程
單線程,即同一個(gè)時(shí)間只能處理一個(gè)任務(wù)。
為什么 JS 是單線程的?作為瀏覽器腳本語言,JavaScript 的主要用途是與用戶互動(dòng),以及操作 DOM 。這決定了它只能是單線程,否則會(huì)帶來很復(fù)雜的同步問題。比如,假定 JavaScript同時(shí)有兩個(gè)線程,一個(gè)線程在某個(gè) DOM 節(jié)點(diǎn)上添加內(nèi)容,另一個(gè)線程刪除了這個(gè)節(jié)點(diǎn),這時(shí)瀏覽器應(yīng)該以哪個(gè)線程為準(zhǔn)?
單線程就意味著,所有任務(wù)都需要排隊(duì),前一個(gè)任務(wù)結(jié)束,才能執(zhí)行后一個(gè)任務(wù)。如果前一個(gè)任務(wù)耗時(shí)很長,那么后一個(gè)任務(wù)就不得不一直等待,于是乎,JS 設(shè)計(jì)者們把所有任分成兩類,同步和異步。
- 同步:只有前一個(gè)任務(wù)執(zhí)行完畢,才能執(zhí)行后一個(gè)任務(wù)
- 異步:當(dāng)同步任務(wù)執(zhí)行到某個(gè) WebAPI 時(shí),就會(huì)觸發(fā)異步操作,此時(shí)瀏覽器會(huì)單獨(dú)開線程去處理這些異步任務(wù)。
步任務(wù)和異步任務(wù)的執(zhí)行過程:
回調(diào)地獄
如果嵌套變多,代碼層次就會(huì)變深,維護(hù)難度也隨之增加。
這就被稱為 “回調(diào)地獄” 或者“回調(diào)深淵”。
2. Promise 基本語法
Promise 就是為了解決“回調(diào)地獄”問題的,它可以將異步操作的處理變得很優(yōu)雅。
// 創(chuàng)建Promise實(shí)例 const promise = new Promise(function(resolve, reject) {// ... some codeif ( /* 異步操作成功 */ ) {resolve(value)} else {reject(error)} })Promise構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù),該函數(shù)的兩個(gè)參數(shù)分別是resolve和reject。它們是兩個(gè)函數(shù),由 JavaScript 引擎提供,不用自己部署。
- 處理結(jié)果正常的話,調(diào)用resolve(處理結(jié)果值),將Promise對象的狀態(tài)從“未完成”變?yōu)椤俺晒Α?#xff08;即從 pending 變?yōu)?resolved),在異步操作成功時(shí)調(diào)用,并將異步操作的結(jié)果,作為參數(shù)傳遞出去
- 處理結(jié)果錯(cuò)誤的話,調(diào)用reject(Error對象),將Promise對象的狀態(tài)從“未完成”變?yōu)椤笆 ?#xff08;即從 pending 變?yōu)?rejected),在異步操作失敗時(shí)調(diào)用,并將異步操作報(bào)出的錯(cuò)誤,作為參數(shù)傳遞出去。
Promise 內(nèi)部是有狀態(tài)的(pending、fulfilled、rejected),Promise 對象根據(jù)狀態(tài)來確定執(zhí)行哪個(gè)方法。Promise 在實(shí)例化的時(shí)候狀態(tài)是默認(rèn) pending 的,當(dāng)異步操作是完成的,狀態(tài)會(huì)被修改為 fulfilled,如果異步操作遇到異常,狀態(tài)會(huì)被修改為 rejected,可以通過下圖來看下狀態(tài)的走向:
狀態(tài)轉(zhuǎn)化是單向的,不可逆轉(zhuǎn),已經(jīng)確定的狀態(tài)(fulfilled/rejected)無法轉(zhuǎn)回初始狀態(tài)(pending),而且只能是從 pending 到 fulfilled 或者 rejected
3. Promise.prototype.then()
var promise = new Promise(function(resolve, reject) {resolve('傳遞給then的值') }) promise.then(function(value) {console.log(value) }, function(error) {console.error(error) })這段代碼創(chuàng)建一個(gè) Promise 對象,定義了處理 onFulfilled 和 onRejected 的函數(shù)(handler),然后返回這個(gè) Promise 對象;當(dāng)執(zhí)行resolve時(shí),會(huì)進(jìn)入then方法的成功回調(diào)方法。then方法的第一個(gè)方法為成功回調(diào),第二個(gè)方法為失敗的回調(diào),參數(shù)為resolve/reject傳遞的參數(shù)。
4. Promise.prototype.catch()
使用 Promise 對象的 catch 方法來捕獲異步操作過程中出現(xiàn)的任何異常。
function test() {return new Promise((resolve, reject) => {reject(new Error('es'))}) }test().catch((e) => {console.log(e.message) // es })reject 不會(huì)觸發(fā)catch,new Error會(huì)觸發(fā)catch,不建議在 Promise 內(nèi)部使用 throw 來觸發(fā)異常,而是使用 reject(new Error()) 的方式來做,因?yàn)?throw 的方式并沒有改變 Pronise 的狀態(tài)
5. Promise.resolve()
一般情況下我們都會(huì)使用 new Promise() 來創(chuàng)建 Promise 對象,但是除此之外我們也可以使用其他方法。
在這里,我們將會(huì)學(xué)習(xí)如何使用 Promise.resolve 和 Promise.reject 這兩個(gè)靜態(tài)方法。
new Promise(function(resolve) {resolve(42) })Promise.resolve(42).then(function(value) {console.log(value) })Promise.resolve 作為 new Promise() 的快捷方式,在進(jìn)行 Promise 對象的初始化或者編寫測試代碼的時(shí)候都非常方便。
6. Promise.reject()
Promise.reject(error) 是和 Promise.resolve(value) 類似的靜態(tài)方法,是 new Promise() 方法的快捷方式。
new Promise(function(resolve, reject) {reject(new Error('出錯(cuò)了')) })Promise.reject(new Error('Error!'))7. Promise.all()
Promise.all 生成并返回一個(gè)新的 Promise 對象,所以它可以使用 Promise 實(shí)例的所有方法。參數(shù)傳遞promise數(shù)組中所有的 Promise 對象都變?yōu)閞esolve的時(shí)候,該方法才會(huì)返回, 新創(chuàng)建的 Promise 則會(huì)使用這些 promise 的值。
如果參數(shù)中的任何一個(gè)promise為reject的話,則整個(gè)Promise.all調(diào)用會(huì)立即終止,并返回一個(gè)reject的新的 Promise 對象。
8. Promise.race()
Promise.race 生成并返回一個(gè)新的 Promise 對象。參數(shù) promise 數(shù)組中的任何一個(gè) Promise 對象如果變?yōu)?resolve 或者 reject 的話, 該函數(shù)就會(huì)返回,并使用這個(gè) Promise 對象的值進(jìn)行 resolve 或者 reject。
var p1 = Promise.resolve(1) var p2 = Promise.resolve(2) var p3 = Promise.resolve(3) Promise.race([p1, p2, p3]).then(function(value) {console.log(value) // 1 })總結(jié)
以上是生活随笔為你收集整理的【ES6(2015)】Promise的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pythonjson序列化_Python
- 下一篇: 【ES9(2018)】RegExp扩展