一: Promise
對象的兩個特點
-
對象的狀態不受外界影響
Promise
對象代表一個異步操作,有三種狀態:pending(進行中)
fulfilled(已成功)
rejected(已失敗)
。
只有異步操作的結果可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態 -
一旦狀態改變,就不會再變,任何時候都可以得到這個結果。
Promise
對象的狀態的改變:- 從
pending
到fulfilled
- 從
pending
到rejected
只要這兩種情況的某種發生,狀態就凝固了,不會再改變,會一直保持這個結果,稱爲
resolved
(已定型) - 從
二:基本用法
ES6規定,Promise
對象是一個構造函數,用來生成Promise
實例
const promise = new Promise(function(resolve,reject){
// ...
if(/*異步操作成功 */){
resolve(value);
}else{
reject(error);
}
});
Promise
構造函數接受一個函數作爲參數,該函數的兩個參數分別是resolve
和reject
。它們是兩個函數,由JavaScript引擎提供。
resolve
函數的作用:
將Promise
對象的狀態從"未完成"變爲"成功",在異步操作成功時調用,並將異步操作的結果,作爲參數傳遞出去;
reject
函數的作用:
將Promise
對象的狀態從“未完成”變爲失敗,在異步操作失敗時調用,並將異步操作報出的錯誤,作爲參數傳遞出去;
Promise
實例生成以後,可以用then
方法指定resolved
狀態和rejected
狀態的回調函數
promise.then(function(value){
// success
},function(error){
// failure
})
其中,第二個函數可選。
注意:
調用resolve
和reject
並不會終結Promise
的參數函數的執行。
new Promise((resolve, reject) => {
resolve(1);
console.log(2);
}).then(r => {
console.log(r);
});
// 2
// 1
一般來說,調用resolve
或reject
以後,Promise
的使命就完成了,後繼操作應該放到then
方法裏面,而不應該直接寫在resolve
或reject
的後面。所以,最好在它們前面加上return
語句,這樣就不會有意外。
new Promise((resolve, reject) => {
return resolve(1);
// 後面的語句不會執行
console.log(2);
})
三:Promise
的方法
原型上的方法:
Promise.prototype.then()
// 爲Promise實例添加狀態改變時的回調函數Promise.prototype.catch()
// 用於指定發生錯誤時的回調函數Promise.prototype.finally()
// 用於指定不管Promise最後狀態如何,都會執行的操作
接受一組Promsie實例作爲參數:
Promise.all()
// 實例中只要有一個被rejected,狀態變爲rejected,返回第一個rejected的實例的返回值;都爲fulfilled,則返回所有實例的返回值數組;Promise.race()
// 只要有一個實例率先改變狀態,那個實例的返回值就被傳出給回調函數;Promise.allSettled()
// 等待所有實例返回結果,無論fulfilled還是rejected;狀態總是fulfilled。返回給回調函數的是一個數組,裏面是每個Promise實例Promise.any()
// 參數實例只要有一個變爲fulfilled狀態,包裝實例就會變成fulfilled
其他
Promise.resolve()
// 將對象轉爲Promise對象Promise.reject()
// 返回一個新的Promsie實例,實例狀態爲rejected;裏面的參數會原封不動作爲reject的理由,變成後續方法的參數。Promise.try()
// 模擬try代碼塊
四:應用
- 加載圖片
我們可以將圖片的加載寫成一個Promise,一旦加載完成,Promise的狀態就發生變化。
const preloadImage = function (path) {
return new Promise(function (resolve, reject) {
const image = new Image();
image.onload = resolve;
image.onerror = reject;
image.src = path;
});
};