Promise,翻譯為承諾,是異步變成的一種解決方案,比傳統(tǒng)的回調(diào)函數(shù)更加合理和更加強(qiáng)大
以往:
doSomething((result)=>{
doSomethingElse(result,(newResult)=>{
doThirdThing(NewReslt,(finalResult)=>{
console.log("得到最終結(jié)果:" + finalResult)
}, failureCallback)
}, failureCallback)
}, failureCallback)
通過Promise
改寫
doSomething().then((result)=>{
return doSomethingElse(result)
})
.then((newReslut)=>{
return doThirdThing(newResult)
})
.then((finalResult)=>{
console.log("得到最終結(jié)果:" + finalResult)
})
.catch(failureCallback)
感受到promise
解決異步操作的優(yōu)點(diǎn):
- 鏈?zhǔn)讲僮鳒p低了編碼難度
- 代碼可讀性明顯增強(qiáng)
狀態(tài)
promise
對(duì)象僅有三種狀態(tài)
-
pending
(進(jìn)行中) -
fulfilled
(已成功) -
rejected
(已失敗)
特點(diǎn)
- 對(duì)象的狀態(tài)不受外界影響,只有異步操作的結(jié)果,可以決定當(dāng)前是哪一種狀態(tài)
- 一旦狀態(tài)改變(從
pending
變?yōu)?code>fulfilled和從pending
變?yōu)?code>rejected),就不會(huì)再變,任何時(shí)候都可以得到這個(gè)結(jié)果
用法
all()
Promise.all()
方法用于將多個(gè)Promise
實(shí)例,包裝成一個(gè)新的Promise
實(shí)例
const p = Promise.all([p1,p2,p3])
接受一個(gè)數(shù)組作為參數(shù),數(shù)組成員都應(yīng)為Promise
實(shí)例
實(shí)例p
的狀態(tài)由p1,p2,p3
決定,分為兩種
- 只有
p1,p2,p3
的狀態(tài)都變成fulfilled
,p
的狀態(tài)才會(huì)變成fulfilled
,此時(shí)p1,p2,p3
的返回值組成一個(gè)數(shù)組,傳給p
的回調(diào)函數(shù) - 只有
p1,p2,p3
當(dāng)中有一個(gè)被rejected
,p
的狀態(tài)就會(huì)變成rejected
,此時(shí)一個(gè)被rejected
的實(shí)例的返回值,會(huì)傳給p
的回調(diào)函數(shù)
注意,如果作為參數(shù)的Promise
實(shí)例,自己定義了catch
方法,那么它被rejected
,并不會(huì)觸發(fā)Promise.all()
的catch
方法
const p1 = new Promise((resolve, reject) => {
resolve('hello');
})
.then(result => result)
.catch(e => e);
const p2 = new Promise((resolve, reject) => {
throw new Error('報(bào)錯(cuò)了');
})
.then(result => result)
.catch(e => e);
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 報(bào)錯(cuò)了]
如果p2
沒有自己的catch
方法,就會(huì)調(diào)用Promise.all()
的catch
方法
const p1 = new Promise((resolve, reject) => {
resolve('hello');
})
.then(result => result);
const p2 = new Promise((resolve, reject) => {
throw new Error('報(bào)錯(cuò)了');
})
.then(result => result);
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// Error: 報(bào)錯(cuò)了
race()
Promise.race()
方法同樣是將多個(gè)Promise
實(shí)例,包裝成一個(gè)新的Promise
實(shí)例
const p = Promise.race([p1,p2,p3])
只要p1,p2,p3
之中有一個(gè)實(shí)例率先改變狀態(tài),p
的狀態(tài)就跟著改變,率先改變的Promise
實(shí)例的返回值則傳遞給p
的回調(diào)函數(shù)
const p = Promise.race([
fetch('/resource-that-may-take-a-while'),
new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('request timeout')), 5000)
})
]);
p
.then(console.log)
.catch(console.error);
allSettled()
Promise.allSettled()
方法接受一組Promise
實(shí)例作為參數(shù),包裝成一個(gè)新的Promise
實(shí)例,只有等到所有的這些參數(shù)實(shí)例都返回結(jié)果,不管是fulfilled
還是rejected
,包裝實(shí)例才會(huì)結(jié)束
const promises = [
fetch('/api-1'),
fetch('/api-2'),
fetch('/api-3'),
];
await Promise.allSettled(promises);
removeLoadingIndicator();