簡介
本文只是針對對Promise
有一定掌握的人士,列舉了Promise需要記住和掌握的關鍵點,不是講Promise的基礎知識。如果是學習Promise,請移步阮一峰老師的部落格。
執行時機
Promise新建後會立即執行,同步的,但是resolved和rejected的回撥函式是非同步的,
但是它的回撥是放在本輪迴圈的末尾執行,並不是放到下次事件迴圈中執行。
Promise
三種狀態
- pending (進行中)
- fulfilled (已成功)
- rejected (已失敗)
三種狀態只能是由pending到fulfilled,或由pending到rejected。狀態一旦改變,不會再變。
在狀態改變後再新增回撥函式仍能立即得到結果,這是與事件的區別,事件結束再去監聽,是得不到結果的。
Resolve
- 引數會傳遞給then回撥函式
- 和rejected都不會終止後續程式碼執行,resolved後面的程式碼仍會執行,除非在resolved時return
- 當resolved的引數是一個promise例項時,會等待上一個promise的狀態返回
Rejected
- 引數傳遞給回撥函式
- 引數通常是Error物件的例項
- 執行丟擲異常,狀態也會變為Rejected
catch
- 不僅狀態變為rejected時會觸發,執行中丟擲的錯誤也會被catch捕獲
- resolve之後丟擲的異常,不會被捕獲,狀態只會更改一次,更改後就不會改變。
- “冒泡”性質,一直向後傳遞,直到被捕獲。也就是說錯誤肯定會被後面的catch捕獲。
- 如果不寫catch,promise有錯誤時,不會有任何反應,不會退出程式、終止指令碼執行,promise和外部程式碼“隔離”(未來可能更改這規則)
- 後面可以繼續跟then和catch
- 返回一個resolved狀態的promise物件,所以如果丟擲一個錯誤,只會觸發第一個catch
then
- 返回的是一個新的promise物件,不是原來的
- 不推薦傳rejected回撥函式,這樣無法捕獲resolved回撥函式中的錯誤
- 如果函式中返回的是一個promise,則後面的then會等待這個promise的結果
finally
finally方法用於指定不管 Promise 物件最後狀態如何,都會執行的操作。
與狀態無關的,resolved或rejected了都會觸發finally(底層也是這麼實現的);
但如果promise沒有返回resolved或rejected是不會執行的。
Promise.all()
Promise.all方法用於將多個 Promise 例項,包裝成一個新的 Promise 例項。
- 自動把包裝的例項轉化成promise例項
- 包裝的promise例項都resolved了它就resolved
- 有一個rejected,它就rejected
- 如果容器中的例項有自己的catch,則不會觸發all的catch
因為catch返回是一個新的promise,catch已經處理了錯誤,返回的promise是resolved的,所以對all來說是兩個resolved的例項
Promise.race()
和all類似,只是它是有一個例項率先改變狀態了,它的狀態就改變了。
Promise.resolve()
把物件轉換成promise物件
引數是一個 Promise 例項
原封不動地返回這個例項。
引數是一個thenable物件
thenable物件指的是具有then方法的物件,比如下面這個物件。
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
resolve會立即執行then方法,然後返回一個resolved的promise物件
引數不是具有then方法的物件,或根本就不是物件
返回一個狀態是resolved的promise物件
不帶有任何引數
直接返回一個resolved狀態的 Promise 物件。(注意promise回撥的執行時機)
Promise.reject()
返回一個狀態為rejected的promise物件
Promise.reject()方法的引數,會原封不動地作為reject的理由,變成後續方法的引數。這一點與Promise.resolve方法不一致
Promise.try
這個有需要一些技術儲備,後續補充。