async await 我的總結

認識async await 首先要從單個熟悉promise

  • async

官方介紹:
async function 聲明將定義一個返回 AsyncFunction 對象的異步函數。
我的理解:dom

1. 首先`async function`會申明定義一個異步執行的函數,無阻塞,不會阻塞後面代碼執行
2. 該函數的返回值是一個Promise對象

執行如下代碼異步

async function testAsync() {
    return '茶樹菇'
  }
  console.log(testAsync());
/*打印結果:
Promise
result: "茶樹菇"
status: "resolved"
「Promise」原型*/

打印結果能夠看出,async 能夠將其後的函數執行結果轉爲Promise對象
既然如此那如下操做也是可行的async

testAsync().then(r => {
    console.log(r);
  });//"茶樹菇"

由如下打印結果可知async function聲明函數是異步函數函數

function t() {
  return new Promise(resolve => {
    resolve('hah')
  })
}
async function t1() {
  const a = await t()
  // console.log(a);
  console.log('t1函數裏');
}
t1()
console.log('我在t1函數調用後');
/*打印結果:
[Log] 我在t1函數調用後
[Log] t1函數裏
*/

  • await

官方介紹
await  操做符用於等待一個Promise 對象。它只能在異步函數 async function 中使用。spa

我的理解:
官方註釋await是在等待一個Promise對象,其實沒有限制,只是根據等待到的結果類型的不一樣有不一樣的操做,若是等到的就是個結果,則await就返回這個值,若是等到的是一Promise對象,則await會阻塞後面代碼執行,等待Promise的結果(因爲awaitasync function申明的異步執行函數,因此不會影響該函數外的其餘代碼執行,隻影響內部)
注意:若是await等待的Promise執行結果除了resolve外,還有異常處理reject,則最好用.catch(err => err)去接收處理異常, 例const a = await t().catch(err => err)code

async function testAsync1() {
    return "茶樹菇";
}

function testAsync2() {
    return new Promise(resolve => {
      resolve('茶樹菇')
    })
}

function testAsync3() {
    return "茶樹菇";
}

async function testFn() {
    const v1 = await testAsync1();
    const v2 = await testAsync2();
    const v3 = await testAsync3();
    console.log(v1);//"茶樹菇"
    console.log(v2);//"茶樹菇"
    console.log(v3);//"茶樹菇"
//因而可知`await`等待的不必定是個`Promise`對象,也能夠是個值
}
testFn();

  • 爲何用async await,對比Promise的優缺點在哪?

模擬個使用場景,以下代碼
需求:隨機產生一個1~2之間的隨機數,用延時器模擬異步操做,判斷該值,若是小於一就成功,大於一失敗對象

//用Promise實現:
function test(resolve, reject) {
    var timeOut = Math.random() * 2;
    console.log('隨機數爲:' + timeOut);
    setTimeout(function() {
      if (timeOut < 1) {
        resolve('小於1, 成功')
      } else {
        reject('大於1,失敗')
      }
    }, timeOut * 1000)
  }
  new Promise(test).then((result) => {
    console.log(result);
  }).catch((reason) => {
    console.log(reason);
  })

打印結果:屏幕快照 2018-03-12 下午2.05.09.pngip

function test2() {
    var timeOut = Math.random() * 2;
    console.log('隨機數爲:' + timeOut);
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (timeOut < 1) {
          resolve('小於1, 成功')
        } else {
          reject('大於1,失敗')
        }
      }, 1000)
    })
  }
  async function asyncFn() {
    const v3 = await test2().catch(er => er)
    console.log(v3);
  }
  asyncFn()

看代碼其實單一的異步處理鏈並不能看出async await的優點,可是若是須要處理多個Promise組成的處理鏈,就能看出區別
假設需求爲:分佈完成,每一步都須要上一步的結果:rem

//每次調用時間都增長200
function logTimeOut(n) {
    return new Promise(resolve => {
      setTimeout(() => resolve(n + 200), n)
    })
  }
//第一步
  function stepOne(n) {
    console.log('第一步所用的時間', n);
    return logTimeOut(n)
  }
//第二步將第一步的結果加上200做爲第二部的初始時間
  function stepTow(m, n) {
    console.log('第二部所用的時間',m, n);
    return logTimeOut(n + m)
  }
//第三步將第二步的結果加上200做爲第三步的初始時間
  function stepThree(k, m, n) {
    console.log('第三部所用的時間', k, m, n);
    return logTimeOut(k + m + n)
  }

首先用Promise實現

//promise實現
  function doIt() {
    console.time("doIt");
    // 第一步初始時間
    const time1 = 200;
    stepOne(time1).then(time2 => {
      return stepTow(time1, time2).then(time3 => [time1, time2, time3])
    })
    .then(timeArr => {
      const [time1, time2, time3] = timeArr
      return stepThree(time1, time2, time3)
    })
    .then(result => {
      console.log('總共計算用時', result);
      console.timeEnd('doIt')
    })
  }
doIt()

使用async awiat

// async await 實現
  async function startIt() {
    console.time("startIt")
    const time1 = 200;
    const time2 = await stepOne(time1)
    const time3 = await stepTow(time1, time2)
    const result = await stepThree(time1, time2, time3)
    console.log('總共計算用時', result);
    console.timeEnd('startIt')
  }

打印結果:屏幕快照 2018-03-12 下午3.02.22.png

這樣對比就能明顯看出區別Promise實現的代碼邏輯複雜,不清晰,不直觀,而經過async await,能夠將異步邏輯,用相似於同步的代碼實現,簡潔明瞭

這是到目前爲止的我的理解,轉載請標明出處

相關文章
相關標籤/搜索