Promise物件,究竟為何物?

陸遠發表於2020-12-20

Promise物件

一、什麼是Promise?

  • Promise是一種非同步操作的解決方案,將寫法複雜的傳統的回撥函式監聽事件的非同步操作用同步程式碼的形式表達出來
  • Promise避免了多級非同步操作的回撥函式巢狀。
  • Promise最早是一個函式庫,現在已經被ES6寫入標準用法。
  • Promise是一種建構函式。
  • Promise例項建立後會立即執行。

二、Promise的基本使用

 

console.log("1")
new Promise((resolve,reject)=>{ // resolve,reject是形式引數,可以是任意寫法,如(res, rej),預設第一個引數實現的是resolve功能;第二個引數實現的是reject功能。
   console.log("2")
    resolve("成功了")
   console.log("3") //resolve()不同於return, resolve()執行完成後後面的程式碼還會執行。
})
執行結果:
  1
  2
  3
  Promise {<fulfilled>: "成功了"}

// 一般狀態改變後的操作放在then回撥函式中
// 所以最好寫成
new Promise((resolve,reject)=>{
   console.log("2")
     return resolve("成功了")
   console.log("3") //不再執行,最好不要在狀態改變後新增操作
})
//resolve()不同於return, resolve()執行完成後後面的程式碼還會執行。

建立例項如下: const p = new Promise((resolve,reject)=>{   //需要實現的非同步操作
  ........
  ........
  if("success") resolve(value)
  // resolve是js引擎提供定的成功後呼叫的函式,作用就是手動將該promise的狀態由,pending(未完成)變為fulfilled(非同步操作成功),然後立即觸發then中的成功回撥函式
    // value值是非同步操作的結果,要傳給後面的回撥函式的值   
  // 值的內容可以根據業務需求自己定;可以是值(普通物件,函式,字元,數字等)也可以是Promise物件
  else reject(new Error) 
  //reject也是js引擎提供的失敗後呼叫的函式,作用就是手動將狀態由pending變為  
  //ejected(非同步操作失敗),引數是丟擲的異常。然後才能觸發then中的錯誤回撥函式或者catch中的回撥函式
})

 

 

 

三、Promise的例項方法

1. Promise.prototype.then()

是什麼:then方法是Promise建構函式原型物件上的方法。

作用: 為例項狀態改變時新增回撥函式(相當於例項狀態變化的監聽函式)。

(1).then方法接受兩個回撥函式作為引數

第一個函式是例項狀態變為resolved(fulfilled)時的回撥函式

第二個函式是例項狀態變為rejected時的回撥函式。

p.then(function(value){
  // 前面例項中resolve方法執行後觸發該方法,即狀態為fulfilled(resolved)狀態時觸發的回撥函式
   // value值就是resolve的引數值
},function(err) {
   // 前面例項中reject方法執行後會觸發該方法,即狀態為rejected時
})

(2).then方法返回一個新的Promise例項,所以可以採用鏈式寫法;

then方法的第一個回撥函式的返回值,即return的值作為下一個then方法裡面的函式傳參。

如果返回值不是Promise物件,會觸發下一個then方法的第一個回撥函式, 並且返回值作為回撥函式的引數;

 

2. Promise.prototype.catch()

是什麼:Promise原型上的catch方法,相當於.then(null/undefined, () => {}),所以返回的也是promise,後面還可以跟then或者catch,只在rejected狀態觸發。

作用: 它可以捕獲所有之前執行的promise中的錯誤,最好所有的promise都在最後使用catch方法,不要在then方法中寫第二個回撥函式

 

p.then((val) => {
  throw new Error("failed");
}).then((val) => {
    // TODO
}).catch((err) => {
   console.log(err); // Error: failed 捕獲內部異常
})

 

 

 

 

3. Promise.prototype.finally()

作用:不管狀態(不能是pending)如何,都會執行的方法。

new Promise((resolve,reject) => {
    // 狀態修改為resolved或者rejected
}).finally(() => {...} )

finally方法最後返回一個promise例項,回撥函式不接受任何值,return方法也被忽略。

但是會預設返回之前的例項物件傳遞的引數。

應用:

如處理檔案完成後,不論成功與否都關閉檔案。

 

四、Promise常用的兩個靜態方法

1、Promise.all()

接受一個陣列(每個引數都是promise例項)作為引數。

如果引數不是promise例項,系統會自動呼叫Promise.resolve()方法,將引數轉為promise例項。

返回一個陣列,引數例項的返回值作為對應的回撥函式的引數

const arr = [1,2];
Promise.all(arr) // 相當於 arr.map(item => Promise.resolve(item))
.then(data => console.log('data-->',data))
//執行結果如下:
// data--> [1,2]

 

2、Promise.race()

引數性質和Promise.all()一樣,都是以引數為Promise例項的陣列為引數。

返回一個新的Promise例項。

作用不一樣:

只要有一個引數例項的狀態發生改變,新的例項的狀態隨之改變,引數例項的返回值作為對應的回撥函式的引數。

 

相關文章