前端開發必備 - ES6 新特性之 let 和 const 命令
前端開發必備 - ES6 新特性之 變量的解構賦值
前端開發必備 - ES6 新特性之 字符串的拓展
前端開發必備 - ES6 新特性之 正則的拓展
前端開發必備 - ES6 新特性之 數值的拓展
前端開發必備 - ES6 新特性之 對象的拓展
前端開發必備 - ES6 新特性之 Symbol
前端開發必備 - ES6 新特性之 Set和Map數據結構
前端開發必備 - ES6 新特性之 Proxy
12.1 概念主要用途:解決異步編程帶來的回調地獄問題。
把Promise簡單理解一個容器,存放着某個未來才會結束的事件(通常是一個異步操作)的結果。通過Promise對象來獲取異步操作消息,處理各種異步操作。
Promise對象2特點:
Promise對象代表一個異步操作,有三種狀态:pending(進行中)、fulfilled(已成功)和rejected(已失敗)。隻有異步操作的結果,可以決定當前是哪一種狀态,任何其他操作都無法改變這個狀态。這也是Promise這個名字的由來,它的英語意思就是“承諾”,表示其他手段無法改變。
- 一旦狀态改變,就不會再變,任何時候都可以得到這個結果。
Promise對象的狀态改變,隻有兩種可能:從pending變為fulfilled和從pending變為rejected。隻要這兩種情況發生,狀态就凝固了,不會再變了,會一直保持這個結果,這時就稱為 resolved(已定型)。如果改變已經發生了,你再對Promise對象添加回調函數,也會立即得到這個結果。這與事件(Event)完全不同,事件的特點是,如果你錯過了它,再去監聽,是得不到結果的。
注意,為了行文方便,本章後面的resolved統一隻指fulfilled狀态,不包含rejected狀态。
Promise缺點
12.2 基本使用
- 無法取消Promise,一旦新建它就會立即執行,無法中途取消。
- 如果不設置回調函數,Promise内部抛出的錯誤,不會反應到外部。
- 當處于pending狀态時,無法得知目前進展到哪一個階段(剛剛開始還是即将完成)。
Promise為一個構造函數,需要用new來實例化。
Promise接收一個函數作為參數,該函數兩個參數resolve和reject,有JS引擎提供。
- resolve作用是将Promise的狀态從pending變成resolved,在異步操作成功時調用,返回異步操作的結果,作為參數傳遞出去。
- reject作用是将Promise的狀态從pending變成rejected,在異步操作失敗時報錯,作為參數傳遞出去。
Promise實例生成以後,可以用then方法分别指定resolved狀态和rejected狀态的回調函數。
幾個例子來理解 :
- 當一段時間過後,Promise狀态便成為resolved觸發then方法綁定的回調函數。
- Promise新建後立刻執行。
異步加載圖片:
resolve函數和reject函數的參數為resolve函數或reject函數:
p1的狀态決定了p2的狀态,所以p2要等待p1的結果再執行回調函數。
調用resolve或reject不會結束Promise參數函數的執行,除了return:
12.3 Promise.prototype.then()
作用是為Promise添加狀态改變時的回調函數,then方法的第一個參數是resolved狀态的回調函數,第二個參數(可選)是rejected狀态的回調函數。
then方法返回一個新Promise實例,與原來Promise實例不同,因此可以使用鍊式寫法,上一個then的結果作為下一個then的參數。
12.4 Promise.prototype.catch()
Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定發生錯誤時的回調函數。
如果 Promise 狀态已經變成resolved,再抛出錯誤是無效的。
當promise抛出一個錯誤,就被catch方法指定的回調函數捕獲,下面三種寫法相同。
一般來說,不要在then方法裡面定義Reject 狀态的回調函數(即then的第二個參數),總是使用catch方法。
12.5 Promise.prototype.finally()
finally方法用于指定不管 Promise 對象最後狀态如何,都會執行的操作。該方法是 ES2018 引入标準的。
finally不接收任何參數,與狀态無關,本質上是then方法的特例。
上面代碼中,如果不使用finally方法,同樣的語句需要為成功和失敗兩種情況各寫一次。有了finally方法,則隻需要寫一次。
finally方法總是會返回原來的值。
12.6 Promise.all()
用于将多個 Promise 實例,包裝成一個新的 Promise 實例,參數可以不是數組,但必須是Iterator接口,且返回的每個成員都是Promise實例。
const p = Promise.all([p1, p2, p3]);
p的狀态由p1、p2、p3決定,分成兩種情況。
- 隻有p1、p2、p3的狀态都變成fulfilled,p的狀态才會變成fulfilled,此時p1、p2、p3的返回值組成一個數組,傳遞給p的回調函數。
- 隻要p1、p2、p3之中有一個被rejected,p的狀态就變成rejected,此時第一個被reject的實例的返回值,會傳遞給p的回調函數。
上面代碼中,promises是包含 6 個 Promise 實例的數組,隻有這 6 個實例的狀态都變成fulfilled,或者其中有一個變為rejected,才會調用Promise.all方法後面的回調函數。
注意:如果Promise的參數中定義了catch方法,則rejected後不會觸發Promise.all()的catch方法,因為參數中的catch方法執行完後也會變成resolved,當Promise.all()方法參數的實例都是resolved時就會調用Promise.all()的then方法。
如果參數裡面都沒有catch方法,就會調用Promise.all()的catch方法。
12.7 Promise.race()
與Promise.all方法類似,也是将多個Promise實例包裝成一個新的Promise實例。
const p = Promise.race([p1, p2, p3]);
與Promise.all方法區别在于,Promise.race方法是p1, p2, p3中隻要一個參數先改變狀态,就會把這個參數的返回值傳給p的回調函數。
12.8 Promise.resolve()将現有對象轉換成 Promise 對象。
const p = Promise.resolve($.ajax('/whatever.json'));
12.9 Promise.reject()返回一個rejected狀态的Promise實例。
注意,Promise.reject()方法的參數,會原封不動地作為reject的理由,變成後續方法的參數。這一點與Promise.resolve方法不一緻。
公衆号:前端自習課
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!