Promise 是 ES2015 新增的對象javascript
Promise 對象有幾個組合方法,能夠將多個承諾合併成一個進行處理java
分別是 Promise.all, Promise.race, Promise.allSettled, Promise.any數組
這些方法均可以接收一組承諾,返回一個新的承諾promise
Promise.all(values)
其中參數 values 是一個可迭代對象,好比數組app
在後文中使用詞語「成功」表示承諾 resolve,「失敗」表示承諾 rejectasync
Promise.all 方法返回的承諾會等到參數中全部的承諾都成功以後纔會成功,只要其中有一個失敗了則返回的承諾也會當即失敗,不會等到那些還掛起的承諾有結果fetch
Promise.all 方法能夠用來處理那些缺一不可的邏輯url
示例:同時發出多個請求都成功後才能進行下一步code
const coffee = fetch('/coffee') const tea = fetch('/tea') const me = fetch('/me') // 我全都要 const res = await Promise.all([coffee, tea, me])
Promise.race 方法返回參數中最快的那個承諾,若是最快的那個承諾成功則返回的承諾也會成功,不然就是失敗,不會等到那些還掛起的承諾有結果orm
示例:給一個複雜任務設定一個超時時間
// 設置一個定時器,時間到了就 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.all 方法的區別
Promise.all 方法須要參數中的全部承諾都成功
而 Promise.allSettled 對參數中的承諾是成功仍是失敗並不關心,只要有結果就行
示例:一次性上傳多個文件,其中上傳成功和上傳失敗的互不影響,在一輪上傳任務完成以後,能夠篩選出那些上傳失敗的從新上傳
const upload = file => { const formData = 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.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 = url document.body.appendChild(img) } catch () { // 一個都沒加載成功 QAQ }
該方法還處於草案中,目前最新的 Chrome, Firefox, Safari 支持