ES6的Promise知識點總結

weixin_34343308發表於2018-04-19

簡介

本文只是針對對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

這個有需要一些技術儲備,後續補充。

相關文章