Promise 是 ES2015 新增的物件
Promise 物件有幾個組合方法,可以將多個承諾合并成一個進行處理
分別是 Promise.all, Promise.race, Promise.allSettled, Promise.any
這些方法都可以接收一組承諾,回傳一個新的承諾
Promise.all(values)
其中引數 values 是一個可迭代物件,比如陣列
在后文中使用詞語“成功”表示承諾 resolve,“失敗”表示承諾 reject
Promise.all
Promise.all 方法回傳的承諾會等到引數中所有的承諾都成功之后才會成功,只要其中有一個失敗了則回傳的承諾也會立即失敗,不會等到那些還掛起的承諾有結果

Promise.all 方法可以用來處理那些缺一不可的邏輯
示例:同時發出多個請求都成功后才能進行下一步
const coffee = fetch('/coffee')
const tea = fetch('/tea')
const me = fetch('/me')
// 我全都要
const res = await Promise.all([coffee, tea, me])
Promise.race
Promise.race 方法回傳引數中最快的那個承諾,如果最快的那個承諾成功則回傳的承諾也會成功,否則就是失敗,不會等到那些還掛起的承諾有結果

示例:給一個復雜任務設定一個超時時間
// 設定一個定時器,時間到了就 reject 一個承諾
const timeout = new Promise((resolve, reject) => {
setTimeout(reject, 3000)
})
const missions = fetch('/missions')
try {
const res = await Promise.race([timeout, missions])
// missions 任務成功
} catch () {
// 時間超過 3 秒了或者任務失敗了
}
Promise.allSettled
Promise.allSettled 方法回傳的承諾物件會等到引數中所有的承諾物件都完成后才成功,無論怎樣該方法回傳的承諾都不會失敗

和 Promise.all 方法的區別
Promise.all 方法需要引數中的所有承諾都成功
而 Promise.allSettled 對引數中的承諾是成功還是失敗并不關心,只要有結果就行
示例:一次性上傳多個檔案,其中上傳成功和上傳失敗的互不影響,在一輪上傳任務完成之后,可以篩選出那些上傳失敗的重新上傳
const upload = file => {
const formData = https://www.cnblogs.com/xyzhanjiang/p/new FormData()
formData.append('file', file)
return fetch('/upload', {
method: 'POST',
body: formData
})
}
document.querySelector('input[type="file"]').addEventListener('change', function(e) {
if (!e.target.value) return
const files = e.target.files
const promises = files.map(file => upload(file))
const res = await Promise.allSettled(promises)
// 全部上傳任務都完成了,找出上傳失敗的重新上傳
})
該方法是 ES2020 新添加的方法
Promise.any
Promise.any 方法回傳一組承諾中最快成功的那個承諾,如果引數中所有承諾都失敗了,那么回傳的承諾也失敗

和 Promise.race 方法的區別
Promise.race 回傳引數中最快的那個承諾,無論它是成功還是失敗
而 Promise.any 關注的是引數中最快同時還必須成功的那個承諾
和 Promise.all 方法的區別
Promise.any 和 Promise.all 是完全相反的
Promise.any 引數中全部承諾都失敗了才會失敗,Promise.all 引數中全部承諾都成功了才會成功
Promise.any 引數中一旦有一個承諾成功了回傳的新承諾就會成功,Promise.all 引數中一旦有一個承諾失敗了回傳的新承諾就會失敗
示例:同時加載一組圖片,但是我們只需要用到其中的一張,就可以用 Promise.any 方法挑選出最先加載成功的那張圖片
const fetchImg = async (url) => {
return fetch(url).then(res => {
if (!res.ok) {
throw new Error('HTTP error!')
} else {
return res.blob()
}
})
}
cosnt img1 = fetchImg('/1.png')
const img2 = fetchImg('/2.png')
try {
const res = await Promise.any([img1, img2])
const url = URL.createObjectURL(res)
const img = document.createElement('img')
img.src = https://www.cnblogs.com/xyzhanjiang/p/url
document.body.appendChild(img)
} catch () {
// 一個都沒加載成功 QAQ
}
該方法還處于草案中,目前最新的 Chrome, Firefox, Safari 支持
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/230551.html
標籤:JavaScript
上一篇:ES6語法,自定義組件的命名
下一篇:zui動態樹形選單二次渲染
