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