Promise與Async Await詳解


 一、什么是promise和async/await?

 1、Promise

  • 所謂Promise,簡單說就是一個容器,里面保存着某個未來才會結束的事件(通常是一個異步操作)的結果。

  • Promise 是異步編程的一種解決方案,比傳統的解決方案(回調函數和事件)更合理和更強大。

  • Promise對象,可以將異步操作以同步操作的流程表達出來,避免了層層嵌套的回調函數。

  • Promise對象提供統一的接口,使得控制異步操作更加容易。

(1)實例方法

可以使用鏈式調用:因為這三個方法的返回值都是promise實例

.then()
// promise狀態為fulfilled(已成功)
// 參數:函數,函數內部的參數是resolve傳過來的實參
.catch()
// promise狀態為rejected(已失敗) 
// 參數:函數,函數內部的參數是reject傳過來的實參
.finally()
// 無論promise狀態是成功還是失敗,都會執行里面的代碼

(2)創建實例

Promise構造函數接受一個函數作為參數,該函數的兩個參數分別是resolvereject,它們是兩個函數

(1)resolve作用是將promise對象狀態從未完成變為成功,異步操作成功時調用,並將異步操作的結果作為參數傳出去。

         reject作用是將promise的狀態從未完成變為失敗,在異步操作失敗時調用,並將異步操作報的錯作為參數傳遞出去

(2)promise對象代表一個異步操作有三個狀態:pending初始狀態,fulfilled操作成功,rejected操作失敗狀態

(3)promise的狀態一經改變,只有兩種可能:從pending變為fulfilled,從pending變為rejected

         狀態發生改變之后就不會再變,會一直保持這個結果,這時就稱為 resolved(已定型)

let promise = new Promise((resolve, reject) => {
        if(1 > 0) {
          // pending => fulfilled
          resolve('success');
        } else {
          // pending => rejected
          reject('error')
        }
      })
      // 訪問promise實例內部的狀態
      promise.then(res => {
        console.log(res)
      }).catch(error => {
        console.error(error)
      })
 // 獲取列表數據
  getList(){
    getList(this.List)
      .then((res) => {
        if (res.code == 200) {
          this.page.total = res.data.total;
          this.page.pageSize = res.data.size;
          this.tableData = res.data.records;
        }
      })
      .catch((err) => {
        console.log(err);
      });
  }

(3)靜態方法

Promise.all([pro1,pro2])
        // 將pro1和pro2包裝成數組作為實參傳遞進去
        // 返回值:promise對象。結果 =》pro1,pro2都成功才成功,有一個失敗就失敗
        
   Promise.race([pro1,pro2])
        // 將pro1和pro2包裝成數組作為實參傳遞進去
        // 返回值:promise對象。結果 =》pro1,pro2誰先回來就用誰都結果(無論成功或者失敗)
        
   Promise.any([pro1,pro2])
        // 將pro1和pro2包裝成數組作為實參傳遞進去
        // 返回值:promise對象。結果 =》pro1,pro2都失敗才失敗,有一個成功就成功
        
   Promise.resolve()
        // 參數:任意
        // 返回值:狀態為fulfilled的promise對象
        
   Promise.reject()
        // 參數:任意
        // 返回值:狀態為rejected的promise對象

2、async

  • async函數是generator函數的語法糖,是ES6的異步編程解決方案

  • async await是對promise的優化,async await是一種更優雅的寫法,將異步的代碼優化為了同步的寫法

(1)關鍵字

  • function關鍵字前加上 async(異步) ​ 異步請求之前,加上 await(等待)

(2)實例

async function findAll() {
    let res = await $.get('......');
    console.table(res.data)
  }
//獲取項目周報列表數據
async getList() {
    let a = this.obj;
    let res = await getList(a);
    this.Data = res.data.records;
    this.total = res.data.total;
}

二、區別

1、函數的前面多了一個async關鍵字。await只能在async中使用。await是阻塞的意思,就是暫停,你一起調用2個接口,第一個執行完,不輸出結果,要等最第二個接口執行完,才返回這兩個的結果。

2、async生成的結果是promise對象,asyncpromise的終結版。

三、為什么使用async/await比較好?

async:

  • async是ES7
  • async語法使得代碼簡潔清晰,不需要寫那么多的箭頭函數,避免了代碼嵌套

  • async在接收上一個返回值為參數時,比較方便

Promise:

  • Promise是ES6
  • Promise主要用於異步任務,將異步的任務隊列化,他主要解決了異步操作不小心就會進入回調地獄模式中,他將回調地獄的嵌套模式改為了鏈式調用模式,利於代碼可讀性和維護性。

  • promise不能在返回表達式的箭頭函數中設置斷點。如果你在.then代碼塊中設置斷點,進入下一步的話,調試器不會跳到下一個.then,因為他只會跳過異步代碼。

// 比如這樣的場景,調用promise1,使用promise1的返回結果去調用promise2,然后使用兩者的結果去調用promise3
const maskRequest = () =>{
    return promise1().then(res1=>{
        return promise2(res1).then(res2=>{
            return promise3(res1,res2)
        })
    })
}

這樣的操作會導致代碼嵌套很多,不易於解讀。

使用async/await的話代碼就變得異常的簡單和直觀

const maskRrequest =  async()=>{
    const res1 = await promise1()
    const res2 = await promoise2(res1)
    return await promise( res1 , res2 )    
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM