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實例。
作用不一樣:
只要有一個參數實例的狀態發生改變,新的實例的狀態隨之改變,參數實例的返回值作為對應的回調函數的參數。