javascript異步之Promise.all()、Promise.race()、Promise.finally()

同期異步系列文章推薦
談一談javascript異步
javascript異步中的回調
javascript異步與promise
javascript異步之Promise.resolve()、Promise.reject()
javascript異步之Promise then和catch
javascript異步之async(一)
javascript異步之async(二)
javascript異步實戰
javascript異步總結歸檔javascript

今天咱們繼續討論promise
網絡上關於PromiseAPI使用的文章多如牛毛,爲了保持javascript異步系列文章的完整性,如今對promise的API進行簡單全面的介紹html

準備工做

我在easy-mock添加了三個接口,備用

依然使用axios進行ajax請求java

Promise.all()

Promise.all()有點像「並行」
咱們看一個栗子ios

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>promise</title>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>

<body>
  <script>
    {
      const p1 = axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise1')
        .then(({
          data
        }) => {
          console.log('p1成功啦');
          return data.data
        })

      const p2 = axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise2')
        .then(({
          data
        }) => {
          console.log('p2成功啦');
          return data.data
        })

      const p3 = axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/mock')
        .then(({
          data
        }) => {
          console.log('p3成功啦');
          return data.data
        })

      const p = Promise.all([p3, p1, p2])
        .then(arr => {
          console.log(arr);
          console.log('Promise.all成功啦');   
        })
        .catch(err=>{
          console.log(err,'Promise.all錯啦');
        })
    }
  </script>
</body>

</html>

咱們知道axios返回的是一個promise對象,咱們能夠看下es6

console.log(p1);


Promise.all就是用於將多個 Promise 實例,包裝成一個新的 Promise 實例
Promise.all,接收一個數組做爲參數,數組的每一項都返回Promise實例
咱們重點看這段代碼ajax

const p = Promise.all([p3, p1, p2])
        .then(arr => {
          console.log(arr);
          console.log('Promise.all成功啦');   
        })
        .catch(err=>{
          console.log(err,'Promise.all錯啦');
        })

p1,p2,p3都是返回promise實例,Promise.all不關心他們的執行順序,若是他們都返回成功的狀態,Promise.all則返回成功的狀態,輸出一個數組,是這三個p1,p2,p3的返回值,數組的順序和他們的執行順序無關,和他們做爲參數排列的順序有關
咱們看下輸出

爲了是拉長接口三的返回時間我對接口三的數據進行了修改,返回值是長度1000-2000之間的隨機數組,因此p3的執行要晚於p1和p2,
但咱們輸出的arr,p3依然在前面,這給咱們帶來一個便利,返回值數組的順序和方法的執行順序無關,能夠進行人爲進行控制
咱們將p1作一下改動,使p1報錯axios

const p1 = axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise1')
        .then(({
          data
        }) => {
          console.log('p1成功啦');
          return xxxx.data//將data.data修改成xxxx.data
        })


若是有一個返回失敗(reject),Promise.all則返回失敗(reject)的狀態,此時第一個被reject的實例的返回值,會傳遞給P的回調函數。
三個promise實例參數之間是「與」的關係,所有成功,Promise.all就返回成功,有一個失敗,Promise.all就返回失敗
換個角度說,一個promise的執行結果依賴於另外幾個promise的執行結果,
例如:
幾個ajax所有執行完了,才能渲染頁面,
幾個ajax所有執行完了,才能作一些數據的計算操做,
不關心執行順序,只關心集體的執行結果數組

Promise.race()

Promise中的競態,用法和Promise.all相似,對應參數的要求和Promise.all相同,傳入一個數組做爲參數,參數要返回一個Promise實例
race就是競爭的意思,數組內的Promise實例,誰執行的快,就返回誰的執行結果,無論是成功仍是失敗promise

const p = Promise.race([p3, p1, p2])
        .then(res => {
          console.log(res);
          console.log('Promise.all成功啦');   
        })
        .catch(err=>{
          console.log(err,'Promise.all錯啦');
        })


經過輸出咱們發現
p1是第一個完成的,因此p的返回結果就是p1的執行結果
並且就算完成,可是 進程不會當即中止,還會繼續執行下去。網絡

關於race的使用場景

搜了一下,不少文章都說是用來解決網絡超時的提示,相似於下面這樣

const p3 = axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/mock')
        .then(({
          data
        }) => {
          console.log('p3成功啦');
          return data.data
        })
      const p4 = new Promise(function (resolve, reject) {
        setTimeout(() => reject(new Error('網絡鏈接超時')), 50)
      })
     const p = Promise.race([p3, p4])
        .then(res => console.log(res))
        .catch(err => console.log(err));

p3的ajax和50ms的定時器比較,看誰執行的快,若是超過了50ms,p3的ajax還沒返回,就告知用戶網絡鏈接超時
這裏有個問題,就算提示超時了,p3還在繼續執行,它並無停下來,直到有狀態返回
我的觀點:race能夠用來爲ajax請求的時長劃定範圍,若是ajax請求時長超過xxxms會執行某個方法,或者ajax請求時長不超過xxms會執行某個方法,總之,race的應用空間不是很大

Promise.finally()

finally方法用於指定無論 Promise 對象最後狀態如何,都會執行的操做。該方法是 ES2018 引入標準的。

const p = Promise.race([p3, p4])
        .then(res => console.log(res))
        .catch(err => console.log(err))
        .finally(() => {
          console.log("finally的執行與狀態無關")
        });

當promise獲得狀態(不論成功或失敗)後就會執行finally,

原文連接

參考連接
Promise 對象
Promise.prototype.finally

相關文章
相關標籤/搜索