一、Promise簡介
1、Promise是什么?
Promise是一個對象,代表一個異步操作的最終完成或者失敗。
2、Promise的狀態
pendding:初始狀態,既不是成功,也不是失敗狀態
fulfiled:操作成功
rejected:操作失敗
pendding狀態的Promise對象,可能會變為fulfiled狀態並傳遞一個值給相應的狀態處理方法,也可能變為rejected狀態並傳遞失敗信息。
3、Promise的特點
(1)、狀態不會受到外界影響,只有異步操作的結果才能決定當前是哪一種狀態,其他操作無法改變
(2)、一旦狀態改變,就不會再變,任何時候都可以得到這個結果。
4、語法
new Promise ( function( resolve, reject ){ ... })
resolve:將Promise的狀態置為fulfiled
reject:將Promise的狀態置為rejected
5、Promise缺點
(1)、一旦創建Promise就會立即執行,中途無法取消
(2)、如果不設置回調函數,Promise內部拋出錯誤不會反應到外部
(3)、處於pennding狀態時,無法得知目前進展到哪一步
6、Promise對象的then方法
語法:.( onfulfiled , onrejected)=>{}
then方法有兩個參數,都是函數類型,分別為onfulfiled以及onrejected,當Promise的狀態為fulfiled時,調用then的onfulfiled方法,當Promise的狀態為rejected時,調用then的onrejected方法
onfulfiled函數:成功的回調函數 (value)=> { }
onrejected函數:失敗的回調函數 (reason ) => { }
7、一個簡單的Promise
new Promise((resolve, reject) => {
setTimeout(() => {
// resolve('成功狀態');
reject('失敗狀態')
}, 300);
}).then((value) => {
console.log(value); //resolve才會輸出 成功狀態
}, (reason) => {
console.log(reason) //reject才會輸出 失敗狀態
});
二、Promise幾種常用方法
1、Promise.resolve()
返回一個給定值解析后的Promise對象。如果參數本身就是一個Promise
對象,則直接返回這個Promise
對象。
栗子:
//使用靜態Promise.resolve方法
let promise = Promise.resolve('resolve方法');
promise.then((value) => {
console.log(value) //輸出: resolve方法
})
//resolve另外一個promise
let promise1 = Promise.resolve(promise);
promise1.then((value) => {
console.log('resolve另外一個promise:' + value) //輸出: resolve另外一個promise:resolve方法
})
2、Promise.reject()
返回一個帶有拒絕原因的Promise
對象。
栗子:
let promise = Promise.reject('reject方法');
promise.then((value) => { }, (rejected) => {
console.log(rejected) //輸出: reject方法
})
3、Promise.all()
將多個Promise封裝成一個新的Promise,成功時返回的是一個結果數組,失敗時,返回的是最先rejected狀態的值。
使用場景:一次發送多個請求並根據請求順序獲取和使用數據
栗子:
let promise1 = Promise.resolve(1);
let promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('promise2');
}, 2000);
})
let promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('promise3');
}, 1000);
})
let promise4 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('promise4');
}, 1000);
})
let promise5 = Promise.reject('promise5');
Promise.all([promise1, promise2, promise3]).then((values) => {
//三個promise都是成功的,所以會輸出一個數組 console.log(values) // [1, "promise2", "promise3"] })
Promise.all([promise1, promise2, promise3, promise4]).then((values) => { console.log(values) }, (reason) => {
//promise4是失敗的,所以只會返回promise4的失敗結果 console.log(reason) //promise4 })
Promise.all([promise1, promise2, promise3, promise4, promise5]).then((values) => { console.log(values) }, (reason) => {
//promise4個promise5都是失敗的,但是promise5比promise4最先失敗,所以返回promise5的失敗結果 console.log(reason) //promise5 })
4、Promise.race()
返回一個 promise,一旦迭代器中的某個promise解決或拒絕,返回的 promise就會解決或拒絕。
簡單來說,就是多個Promise中,哪個狀態先變為成功或者失敗,就返回哪個Promise的值
let promise1 = new Promise((resolve, reject) => {
//setTimeout第三個以后的參數是作為第一個func()
的參數傳進去,promise1作為resolve的參數
setTimeout(resolve, 500, 'promise1');
});
let promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'promise2');
});
let promise3 = new Promise((resolve, reject) => {
setTimeout(reject, 500, 'promise3');
});
let promise4 = new Promise((resolve, reject) => {
setTimeout(reject, 100, 'promise4');
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value); //promise2 100 <promise1 500 所以輸出: promise2
});
Promise.race([promise3, promise4]).then((value) => {
}, (rejected) => {
console.log(rejected) //promise4 100 < promise3 500 所以輸出: promise4
});
Promise.race([promise2, promise3]).then((value) => {
console.log(value) //promise2 100 < promise3 500 所以會走成功狀態,輸出: promise2
}, (rejected) => {
console.log(rejected)
});
Promise.race([promise1, promise4]).then((value) => {
console.log(value)
}, (rejected) => {
console.log(rejected) //promise4 100 < promise1 500 所以會走失敗狀態,輸出: promise4
});
5、Promise.prototype.catch()
返回一個Promise,並且處理拒絕的情況。
栗子:
let promise = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'promise');
});
promise.then((value) => {
console.log(value); //promise
throw '拋出一個異常' //通過throw 拋出
}).catch((e) => {
console.log(e) //輸出: 拋出一個異常
})
注意:
在異步函數中拋出的錯誤不會被catch捕獲到
let promise1 = new Promise((resolve, reject) => {
setTimeout(() => { throw '拋出一個異常'; }, 1000)
});
promise1.catch((e) => {
console.log(e) //不會執行
})
在resolve后面拋出的錯誤會被忽略
let promise2 = new Promise((resolve, reject) => {
resolve() throw '拋出異常'
});
promise2.catch((e) => {
console.log(e) //不會執行
})