ES6(三) Promise 的基本使用方式

基本用法

關(guān)于Promise的資料,網(wǎng)上有很多了,這里簡(jiǎn)單粗暴一點(diǎn),直接上代碼。
假設(shè)我們要做一個(gè)訪問后端API的函數(shù),那么我們可以這樣模擬一下。

    const mySend = (url, data) => {
      // 接收url 和data,假裝向后端提交
      console.log('url:', url, data)
      // 定義一個(gè)實(shí)例
      const p = new Promise((resolve, reject)=>{
        // resolve,reject是形式參數(shù),可以是任意寫法,如(res, rej)
        // 默認(rèn)第一個(gè)參數(shù)實(shí)現(xiàn)的是resolve功能;
        // 第二個(gè)參數(shù)實(shí)現(xiàn)的是reject功能。
        console.log("假裝訪問了一下后端,并且獲得了數(shù)據(jù)。")
        const data = {
          name: 'jyk',
          time: new Date().valueOf()
        }
        // 成功了,返回給調(diào)用者
        resolve(data) 
        // 不同于return, resolve()執(zhí)行完成后后面的代碼還會(huì)執(zhí)行。
        console.log('resolve后的代碼')
        // 如果 resolve 被調(diào)用了,那么 reject 就不會(huì)被調(diào)用了。
        // 失敗的話,調(diào)用reject返回給調(diào)用者。
        reject('失敗了')
      })
      return p
    }
  • new Promise
    先定義一個(gè)函數(shù),用于接收調(diào)用者的參數(shù)。
    然后生成一個(gè)Promise的實(shí)例,在里面進(jìn)行我們想要的操作。

  • resolve(data)
    如果操作成功就調(diào)用 resolve(data) ,返回給調(diào)用者;

  • reject('失敗了')
    如果操作失敗,就調(diào)用reject('失敗了') ,返回給調(diào)用者。

注意:返回參數(shù)只能有一個(gè),不支持多個(gè)參數(shù),如果需要返回多個(gè),可以組成一個(gè)對(duì)象。

有些例子會(huì)用setTimeout做演示,其實(shí)效果都一樣,不是必須弄個(gè)異步的方式來模擬。

單次調(diào)用

函數(shù)寫好了,怎么調(diào)用呢?其實(shí)調(diào)用方法和axios的使用方式很像,因?yàn)閍xios也是用promis封裝的。

  const submit = () => {
      mySend('/api/person', {id: 122})
        .then((data) => {
          console.log('回調(diào)數(shù)據(jù):', data)
        })
        .catch((error) => {
          console.log(error)
        })
    }

調(diào)用很簡(jiǎn)單,看著也非常眼熟對(duì)吧。

  • then 響應(yīng)成功的回調(diào),
  • catch 響應(yīng)失?。ó惓#┑幕卣{(diào)。
  • 運(yùn)行結(jié)果:
url-data: /api/person {id: 122}
(index):32 假裝訪問了一下后端,并且獲得了數(shù)據(jù)。
(index):39 resolve后的代碼
(index):52 回調(diào)數(shù)據(jù): {name: "jyk", time: 1612084395672}

依次調(diào)用

如果要多次調(diào)用呢?而且要得到上一次返回的數(shù)據(jù),才能發(fā)起下一次的訪問。

  const submitStep = () => {
      mySend('/api/person1', [1,2,3]).then((data) => {
        console.log('第一個(gè)返回:', data)
        return mySend('/api/person2', data) // 發(fā)起第二次請(qǐng)求
      }).then((data) => {
        console.log('第二個(gè)返回:', data)
        return mySend('/api/person3', data) // 發(fā)起第三次請(qǐng)求
      }).then((data) => {
        console.log('第三個(gè)返回:', data)
        return mySend('/api/person4', data) // 發(fā)起第四次請(qǐng)求
      }).then((data) => {
        console.log('第四個(gè)返回:', data)
      })
    }

第一次調(diào)用的回調(diào)函數(shù)里面,使用return的方式,發(fā)起下一次調(diào)用。這樣就可以避免回調(diào)地域。

  • 運(yùn)行結(jié)果:
url-data: /api/person1 (3) [1, 2, 3]
(index):32 假裝訪問了一下后端,并且獲得了數(shù)據(jù)。
(index):39 resolve后的代碼
(index):62 第一個(gè)返回: {name: "jyk", time: 1612084751425}
(index):26 url-data: /api/person2 {name: "jyk", time: 1612084751425}
(index):32 假裝訪問了一下后端,并且獲得了數(shù)據(jù)。
(index):39 resolve后的代碼
(index):65 第二個(gè)返回: {name: "jyk", time: 1612084751426}
(index):26 url-data: /api/person3 {name: "jyk", time: 1612084751426}
(index):32 假裝訪問了一下后端,并且獲得了數(shù)據(jù)。
(index):39 resolve后的代碼
(index):68 第三個(gè)返回: {name: "jyk", time: 1612084751428}
(index):26 url-data: /api/person4 {name: "jyk", time: 1612084751428}
(index):32 假裝訪問了一下后端,并且獲得了數(shù)據(jù)。
(index):39 resolve后的代碼
(index):71 第四個(gè)返回: {name: "jyk", time: 1612084751430}

可以注意一下time的值,前后是對(duì)應(yīng)的。

批量調(diào)用

如果下次調(diào)用不需要上一次的結(jié)果呢?那么能不能一起調(diào)用呢?當(dāng)然是可以的。

    const submitMore = () => {
      Promise.all([
        mySend('/api/person11', [1,2,3]),
        mySend('/api/person22', [4,5,6]),
        mySend('/api/person33', [7,8,9])
      ]).then((data) => {
        console.log("一起調(diào)用,一起返回:")
        console.log('data:', data)
        console.log('data11:', data[0])
        console.log('data22:', data[1])
        console.log('data33:', data[2])
      },(msg) => {
        console.log(msg)
      })
    }
  • Promise.all
    使用 Promise.all,把調(diào)用寫成數(shù)組的形式。
    返回的data也是一個(gè)數(shù)組的形式,其順序會(huì)對(duì)照上面的調(diào)用順序。

  • 運(yùn)行結(jié)果:

url-data: /api/person11 (3) [1, 2, 3]
(index):32 假裝訪問了一下后端,并且獲得了數(shù)據(jù)。
(index):39 resolve后的代碼
(index):26 url-data: /api/person22 (3) [4, 5, 6]
(index):32 假裝訪問了一下后端,并且獲得了數(shù)據(jù)。
(index):39 resolve后的代碼
(index):26 url-data: /api/person33 (3) [7, 8, 9]
(index):32 假裝訪問了一下后端,并且獲得了數(shù)據(jù)。
(index):39 resolve后的代碼
(index):82 一起調(diào)用,一起返回:
(index):83 data: (3) [{…}, {…}, {…}]
  0: {name: "jyk", time: 1612085029968}
  1: {name: "jyk", time: 1612085029969}
  2: {name: "jyk", time: 1612085029970}
  length: 3__proto__: Array(0)
(index):84 data11: {name: "jyk", time: 1612085029968}
(index):85 data22: {name: "jyk", time: 1612085029969}
(index):86 data33: {name: "jyk", time: 1612085029970}

可以看到,先發(fā)起了申請(qǐng),然后結(jié)果會(huì)一起返回。

小結(jié)

這樣看起來就不會(huì)暈了吧。我的想法是,先會(huì)用能夠運(yùn)行起來,以后有空了在去研究原理和其他細(xì)節(jié)。

在線演示:https://naturefwvue.github.io/nf-vue-cnd/ES6/promise/

源碼:https://github.com/naturefwvue/nf-vue-cnd/tree/main/ES6/promise

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容