Promise 之初探

金色海洋(jyk)發表於2020-12-21

陳舊的知識應該更新一下了,先嚐試一下 Promise ,主要參考 https://www.cnblogs.com/whybxy/p/7645578.html

定義一個函式

直接上乾貨,定義一個函式:

const myPost = (url, data) => {
    // 接收url 和data,向後端提交
    console.log('url:', url)
    console.log('data:', data)
    const p = new Promise((resolve,reject)=>{ // resolve,reject是形式引數,可以是任意寫法,如(res, rej),預設第一個引數實現的是resolve功能;第二個引數實現的是reject功能。
      console.log("myPost:")
      data.push('處理完畢') 
      resolve(data) // 返回引數
      // resolve()不同於return, resolve()執行完成後後面的程式碼還會執行。
      reject('失敗了')
    })
    return p
  }

這個函式,假裝要向後端提交申請,然後返回後端給的資料。

const p = new Promise() 定義一個例項,簡單理解,resolve 是成功的回撥函式,reject 是失敗的回撥函式。

注意:這裡只是簡單理解,實際上並不完全是這樣。

單次呼叫

        myPost('url1', [1,2,3]).then((data) => {
          console.log("單次呼叫的結果:")
          console.log(data)
        },(msg) => {
          console.log('myPost的else'+msg)
        })

傳入url和需要提交的資料,然後在then裡面等待結果。then裡面第一個方法是成功的回撥,第二個方法是失敗的回撥。

我們看一下執行結果:

依次呼叫

        myPost('urla', [1,2,3]).then((data) => {
          console.log("第一個呼叫完成:")
          console.log(data)
          return myPost('urlb', data) // 發起第二次請求
        }).then((data) => {
          console.log("第二個呼叫完成:")
          console.log(data)
          return myPost('urlc', data) // 發起第三次請求
        }).then((data) => {
          console.log("第三個呼叫完成:")
          console.log(data)
          return myPost('urld', data) // 發起第四次請求
        }).then((data) => {
          console.log("第四個呼叫完成:")
          console.log(data)
        })

有的時候需要多次向後端提交申請,而且需要前一次申請得到的資料,才能發起下一次申請。
那麼可以用這種依次申請的方式。

先發起第一個申請,然後得到資料,然後依據資料發起第二次申請,同理可以依次發起n次申請。

因為是得到結果才能發起下次申請,所以提交順序和返回順序皆可以控制。

看一下執行結果:

這裡有個小問題,第一次訪問的結果裡面 console.log(data) 出來的是四個陣列元素,這個是期待的,但是開啟看裡面卻有7個。這就奇怪了。

批量一起呼叫

        Promise.all([
          myPost('urla', [1,2,3]),
          myPost('urlb', [1,2,3]),
          myPost('urlc', [1,2,3])
        ]).then((data) => {
            console.log("一起呼叫,一起返回:")
            console.log(data)
            console.log(data[1])
        },(msg) => {
          console.log(msg)
        })

有的時候,向後端發出的申請,可以一起提交,並不需要上次返回的結果,那麼可以這麼寫,這樣是不是比then.then.then的好看多了。

那麼返回的資料是啥樣子的呢?是陣列,順序和上面提交的順序是一致的。

我們來看看結果:

這裡也有個意外,本來以為一起呼叫的結果,會出現在依次訪問的第四次訪問結果的後面。
但是實際情況卻發生了“亂入”。
一起訪問的結果,插入了依次訪問的“內部”。

這裡並沒有使用settimeout來模擬後端訪問,本來以為都是順序執行,但是實際並不是,估計是promise內部的一些原理導致的,先不去研究了,暫時先這樣。第一步先會用,知道返回的順序的特點。

這裡的返回結果,並沒有出現陣列元素數量莫名增加的情況。問題出在哪裡,在繼續研究。

疑問:

  • 你可能會奇怪,這個根本就沒有任何訪問後端的程式碼嘛,忽悠人是不是?
    其實並不是,現在流行的axios就是依據promise來實現的,也就是說axios本身就是一個promise例項,相當於函式裡面的p。
    我們把promise的使用方式理解了之後,使用axios實現向後端的訪問,就輕鬆多了。
    另外這裡是熟悉promise的用法,並不是熟悉axios的用法。

  • 另一個問題是,為啥要自己寫個函式,直接用axios不香嗎?
    這個和個人習慣有關係。我總是習慣自己再多加一層,這樣函式名稱、引數、返回方式就都可以歸我個人來控制了,
    這樣便於應對版本升級,更換第三方類庫,增加自己想要的功能。
    比如我想加入前端儲存的功能,提交的資料在前端 localStorage 裡面儲存一份的話,就可以直接在自己定義的函式裡面實現,而不用在頁面程式碼裡面增加呼叫的函式。

相關文章