Promise對象入門

  • 2020 年 8 月 30 日
  • 筆記

簡介


promise對象可以獲取非同步操作的消息,提供統一的API,各個非同步操作都可以用同樣的方法進行處理。
promise對象不受外界影響,其有三種狀態:pending(進行中)、fulfilled(成功)、rejected(失敗),只有非同步操作的結果可以決定當前狀態,一旦狀態改變就不可以再變化,狀態改變方向有兩種:pending -> fulfilled、pending -> rejected
promise對象的意義就在於將非同步操作以同步操作的流程表達,避免層層嵌套的回調函數

基本用法

let promise = new Promise(function (resolve, reject) {
  if () {
    resolve(value) // 非同步操作成功
  } else {
    reject(error) // 失敗拋錯
  }
})

Promise構造函數接受一個函數作為參數,該函數有兩個參數:resolve、reject,當執行resolve函數時Promise對象狀態pending -> fulfilled,當執行reject時Promise對象狀態pending -> rejected

promise.then(function (value) {
  
}, function (error) {
  
})

Promise實例生成以後,可以用then方法分別指定resolved狀態和rejected狀態的回調函數,第二個參數為可選參數,例子:

let promise = new Promise(function (resolve, reject) {
  console.log('promise')
  resolve('11')
})
promise.then(function (value) {
  console.log(value)
})
console.log('22')

執行結果'promise -> 22 -> 11',promise對象新建後立即執行,then方法的回調會在所有同步任務執行完成後執行

catch

promise.prototype.catch()是then()方法的別名,用於指定發生錯誤時的回調函數

new Promise(function () {

}).then(() => {

}).catch(err => {
  console.log(err)
})

如果非同步操作拋出錯誤,狀態就會變為reject,就會調用catch中的回調,當狀態為resolve,執行then方法中的回調時,若報錯同樣回進入catch的回調
意義:當我們使用promise非同步操作時,但是沒有使用catch捕獲錯誤時,若promise非同步執行報錯時,外部程式碼並不會接收到錯誤,而是繼續執行不受影響

const someAsyncThing = function() {
  return new Promise(function(resolve, reject) {
    resolve(x);
  });
};
someAsyncThing().then(function() {
  console.log('ok');
});
setTimeout(() => { console.log('continue') }, 100);

如程式碼所示,x變數並沒有定義,期待的操作是執行報錯,然後停止運行,實際上continue會執行輸出,這說明當沒有catch捕獲錯誤時,外部程式碼不會知道Promise對象內部執行已經報錯,因此會繼續執行。

finally

不管Promise對象最後結果如何,都會執行的操作,finally方法中的回調函數不接受任何參數

promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});

all

Promise.all方法用於將多個Promise實例包裝成一個新的實例

Promise.all([p1,p2,p3]).then((array) => {
  
}).catch((err) => {
  
})

只有p1、p2、p3的狀態都變成fulfilled,p的狀態才會變成fulfilled,此時p1、p2、p3的返回值組成一個數組,傳遞給p的回調函數。
只要p1、p2、p3之中有一個被rejected,p的狀態就變成rejected,此時第一個被reject的實例的返回值,會傳遞給p的回調函數。

Tags: