Promise.any 的作用是什么,如何自己實(shí)現(xiàn)一個(gè) Promise.any
點(diǎn)擊上方 三分鐘學(xué)前端,關(guān)注公眾號(hào)
回復(fù)交流,加入前端編程面試算法每日一題群
引言
本文從五個(gè)方面介紹 Promise.any :
Promise.any的作用Promise.any應(yīng)用場(chǎng)景Promise.anyvsPromise.allPromise.anyvsPromise.race手寫 Promise.any實(shí)現(xiàn)
下面正文開(kāi)始??
Promise.any
Promise.any() 是 ES2021 新增的特性,它接收一個(gè) Promise 可迭代對(duì)象(例如數(shù)組),
只要其中的一個(gè) promise成功,就返回那個(gè)已經(jīng)成功的promise如果可迭代對(duì)象中沒(méi)有一個(gè) promise成功(即所有的promises都失敗/拒絕),就返回一個(gè)失敗的promise和AggregateError類型的實(shí)例,它是Error的一個(gè)子類,用于把單一的錯(cuò)誤集合在一起
const promises = [
Promise.reject('ERROR A'),
Promise.reject('ERROR B'),
Promise.resolve('result'),
]
Promise.any(promises).then((value) => {
console.log('value: ', value)
}).catch((err) => {
console.log('err: ', err)
})
// value: result
如果所有傳入的 promises 都失敗:
const promises = [
Promise.reject('ERROR A'),
Promise.reject('ERROR B'),
Promise.reject('ERROR C'),
]
Promise.any(promises).then((value) => {
console.log('value:', value)
}).catch((err) => {
console.log('err:', err)
console.log(err.message)
console.log(err.name)
console.log(err.errors)
})
// err:AggregateError: All promises were rejected
// All promises were rejected
// AggregateError
// ["ERROR A", "ERROR B", "ERROR C"]
Promise.any 應(yīng)用場(chǎng)景
從最快的服務(wù)器檢索資源
來(lái)自世界各地的用戶訪問(wèn)網(wǎng)站,如果你有多臺(tái)服務(wù)器,則盡量使用響應(yīng)速度最快的服務(wù)器,在這種情況下,可以使用
Promise.any()方法從最快的服務(wù)器接收響應(yīng)
function getUser(endpoint) {
return fetch(`https://superfire.${endpoint}.com/users`)
.then(response => response.json());
}
const promises = [getUser("jp"), getUser("uk"), getUser("us"), getUser("au"), getUser("in")]
Promise.any(promises).then(value => {
console.log(value)
}).catch(err => {
console.log(err);
})
顯示第一張已加載的圖片(來(lái)自MDN)
在這個(gè)例子,我們有一個(gè)獲取圖片并返回
blob的函數(shù),我們使用Promise.any()來(lái)獲取一些圖片并顯示第一張有效的圖片(即最先 resolved 的那個(gè) promise)
function fetchAndDecode(url) {
return fetch(url).then(response => {
if(!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
} else {
return response.blob();
}
})
}
let coffee = fetchAndDecode('coffee.jpg');
let tea = fetchAndDecode('tea.jpg');
Promise.any([coffee, tea]).then(value => {
let objectURL = URL.createObjectURL(value);
let image = document.createElement('img');
image.src = objectURL;
document.body.appendChild(image);
})
.catch(e => {
console.log(e.message);
});
Promise.any vs Promise.all
Promise.any() 和 Promise.all() 從返回結(jié)果來(lái)看,它們 彼此相反 :
Promise.all():任意一個(gè)promise被reject,就會(huì)立即被reject,并且reject的是第一個(gè)拋出的錯(cuò)誤信息,只有所有的promise都resolve時(shí)才會(huì)resolve所有的結(jié)果Promise.any():任意一個(gè)promise被resolve,就會(huì)立即被resolve,并且resolve的是第一個(gè)正確結(jié)果,只有所有的promise都reject時(shí)才會(huì)reject所有的失敗信息
另外,它們又有不同的 重點(diǎn) :
Promise.all()對(duì)所有實(shí)現(xiàn)都感興趣。相反的情況(至少一個(gè)拒絕)導(dǎo)致拒絕。Promise.any()對(duì)第一個(gè)實(shí)現(xiàn)感興趣。相反的情況(所有拒絕)導(dǎo)致拒絕。
Promise.any vs Promise.race
Promise.any() 和 Promise.race() 的 關(guān)注點(diǎn) 不一樣:
Promise.any():關(guān)注于Promise是否已經(jīng)解決Promise.race():主要關(guān)注Promise是否已經(jīng)解決,無(wú)論它是被解決還是被拒絕
手寫 Promise.any 實(shí)現(xiàn)
Promise.any 只要傳入的 promise 有一個(gè)是 fullfilled 則立即 resolve 出去,否則將所有 reject 結(jié)果收集起來(lái)并返回 AggregateError
MyPromise.any = function(promises){
return new Promise((resolve,reject)=>{
promises = Array.isArray(promises) ? promises : []
let len = promises.length
// 用于收集所有 reject
let errs = []
// 如果傳入的是一個(gè)空數(shù)組,那么就直接返回 AggregateError
if(len === 0) return reject(new AggregateError('All promises were rejected'))
promises.forEach((promise)=>{
promise.then(value=>{
resolve(value)
},err=>{
len--
errs.push(err)
if(len === 0){
reject(new AggregateError(errs))
}
})
})
})
}
來(lái)自:https://github.com/sisterAn/blog
最后
評(píng)論
圖片
表情
