詳解promise、async、await以及在小程序雲函數中使用promise

首先解釋一下什麼是同步、什麼是異步

同步:做飯的時候,先燒水,等水燒好的時候再去做菜
異步:做好的時候,先燒水,等待水燒好的過程中,同時去做菜

使用promise的目的就是爲了避免 callback hell(地獄回調)例如:

 setTimeout(() => {
      console.log(1)
      setTimeout(() => {
        console.log(2)
        setTimeout(() => {
          console.log(3)
        }, 3000)
      }, 2000)
    }, 1000)

像這種代碼可讀性和可維護性都不高,所以es6才提出了promise這種方法。

promise一共有三種狀態
1.pending //既不是成功,也不是失敗
2.fulfilled //成功
3. rejected //失敗

以下是例子

//resolve代表成功,reject代表失敗
  new Promise((resolve,reject)=>{
    setTimeout(()=>{
      console.log(1)
      resolve()
    },1000).then(res=>{
      setTimeout(()=>{
      console.log(2)
      },2000)
    })
  })

這樣就解決了地獄回調的問題。

除此之外,promise還有兩個很重要的方法 Promise.all
Promise.all代表等待全部promise執行完成後再執行。

舉個例子

   let p1 = new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('p1')
        resolve('p1') //可以進行傳參
      }, 1000)
    })
    let p2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('p2')
        resolve('p2')
      }, 2000)
    })
    let p3 = new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('p3')
        resolve('p3')
      }, 3000)
    })

    Promise.all([p1, p2, p3]).then(res => {
      console.log('全部完成')
      console.log(res)
    }).catch(err => {
       console.log('失敗')
       console.log(err)
    })

promise.all會等待p1,p2,p3完成請求之後纔會執行,如果執行失敗纔會進入catch方法。
console的結果如下:

在這裏插入圖片描述
其中promise.all成功調用之後res接受的參數是p1、p2、p3 resolve()傳遞進來的。

如果我們把p1、p2、p3 其中一個改爲調用失敗的話

 let p1 = new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('p1')
        reject('p1') //可以進行傳參
      }, 1000)
    })

那麼promise.all就會執行失敗,也就是promise.all一定要三個都執行成功之後才能夠成功執行。

還有一個方法是Promise.race,它的意思是,只要有一個任務完成了就算是完成了,還是剛剛那個例子,把Promise.all改爲Promise.race的話,輸入的結果如下:
在這裏插入圖片描述
promise.race一般用於判斷是否請求超時。

async、 await

在小程序中默認是不支持async、await的,如果需要使用的話,方法如下
1.在你的項目中創建一個文件夾utils
2.在utils文件夾下創建一個js文件runtime.js
runtime.js的代碼如下:runtime.js
3.在你需要使用的小程序js中引入

//注意這裏一定要用regeneratorUntime,不用的話會報錯
import regeneratorUntime from '../../utils/runtime.js'

然後就可以開始使用 async await了。

那麼async await怎麼使用呢?下面舉個例子說明async、await怎麼使用

首先定義一個定時的函數

 timeout() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log(1)
        resolve('resolve')
      }, 1000)
    })
  }

(這個函數會在1s之後在控制檯打印出一個1)

然後我需要在一個函數中調用這個函數並取得這個值,例如我需要在foo這個函數中調用這個方法,然後在頁面初始渲染的時候渲染這個foo()函數

async foo(){
    this.timeout()
}

顯然如果使用上面那一段代碼的話在控制檯是打印不出1的,因爲timeout()函數是一個異步的操作
所以我們就需要使用到async、await方法

async foo(){
    let res = await this.timeout()
    console.log(res)
}

這樣才能保證,timeout()函數執行完成之後才賦值給res
注意! 使用await前面一定要有一個async,不然的話執行是沒有效果的。
結果如下:

在這裏插入圖片描述大家可以看一下代碼行數,是不是先執行了timeout這個方法然後才執行foo函數中的console。

以上就是簡單的async、await的簡單使用方法,實際使用中肯定比這個複雜的多,希望這篇文章對大家有所幫助

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章