async await 個(gè)人總結(jié)

認(rèn)識(shí)async await 首先要從單個(gè)熟悉

  • async
    官方介紹:
    async function 聲明將定義一個(gè)返回 AsyncFunction 對(duì)象的異步函數(shù)。
    個(gè)人理解:
    1. 首先async function會(huì)申明定義一個(gè)異步執(zhí)行的函數(shù),無(wú)阻塞,不會(huì)阻塞后面代碼執(zhí)行
    2. 該函數(shù)的返回值是一個(gè)Promise對(duì)象

執(zhí)行以下代碼

async function testAsync() {
    return '茶樹(shù)菇'
  }
  console.log(testAsync());
/*打印結(jié)果:
Promise
result: "茶樹(shù)菇"
status: "resolved"
“Promise”原型*/

打印結(jié)果可以看出,async 可以將其后的函數(shù)執(zhí)行結(jié)果轉(zhuǎn)為Promise對(duì)象
既然如此那以下操作也是可行的

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

由以下打印結(jié)果可知async function聲明函數(shù)是異步函數(shù)

function t() {
  return new Promise(resolve => {
    resolve('hah')
  })
}
async function t1() {
  const a = await t()
  // console.log(a);
  console.log('t1函數(shù)里');
}
t1()
console.log('我在t1函數(shù)調(diào)用后');
/*打印結(jié)果:
[Log] 我在t1函數(shù)調(diào)用后
[Log] t1函數(shù)里
*/

  • await
    官方介紹
    await 操作符用于等待一個(gè)Promise 對(duì)象。它只能在異步函數(shù) async function 中使用。

    個(gè)人理解:
    官方注釋await是在等待一個(gè)Promise對(duì)象,其實(shí)沒(méi)有限制,只是根據(jù)等待到的結(jié)果類(lèi)型的不同有不同的操作,如果等到的就是個(gè)結(jié)果,則await就返回這個(gè)值,如果等到的是一Promise對(duì)象,則await會(huì)阻塞后面代碼執(zhí)行,等待Promise的結(jié)果(由于awaitasync function申明的異步執(zhí)行函數(shù),所以不會(huì)影響該函數(shù)外的其他代碼執(zhí)行,只影響內(nèi)部)
    注意:如果await等待的Promise執(zhí)行結(jié)果除了resolve外,還有異常處理reject,則最好用.catch(err => err)去接收處理異常, 例const a = await t().catch(err => err)

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

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

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

async function testFn() {
    const v1 = await testAsync1();
    const v2 = await testAsync2();
    const v3 = await testAsync3();
    console.log(v1);//"茶樹(shù)菇"
    console.log(v2);//"茶樹(shù)菇"
    console.log(v3);//"茶樹(shù)菇"
//由此可見(jiàn)`await`等待的不一定是個(gè)`Promise`對(duì)象,也可以是個(gè)值
}
testFn();

  • 為什么用async await,對(duì)比Promise的優(yōu)缺點(diǎn)在哪?
    模擬個(gè)使用場(chǎng)景,如下代碼
    需求:隨機(jī)產(chǎn)生一個(gè)1~2之間的隨機(jī)數(shù),用延時(shí)器模擬異步操作,判斷該值,如果小于一就成功,大于一失敗
//用Promise實(shí)現(xiàn):
function test(resolve, reject) {
    var timeOut = Math.random() * 2;
    console.log('隨機(jī)數(shù)為:' + 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);
  })

打印結(jié)果:
屏幕快照 2018-03-12 下午2.05.09.png
function test2() {
    var timeOut = Math.random() * 2;
    console.log('隨機(jī)數(shù)為:' + 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()

看代碼其實(shí)單一的異步處理鏈并不能看出async await的優(yōu)勢(shì),但是如果需要處理多個(gè)Promise組成的處理鏈,就能看出區(qū)別
假設(shè)需求為:分布完成,每一步都需要上一步的結(jié)果:

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

首先用Promise實(shí)現(xiàn)

//promise實(shí)現(xiàn)
  function doIt() {
    console.time("doIt");
    // 第一步初始時(shí)間
    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('總共計(jì)算用時(shí)', result);
      console.timeEnd('doIt')
    })
  }
doIt()

使用async awiat

// async await 實(shí)現(xiàn)
  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('總共計(jì)算用時(shí)', result);
    console.timeEnd('startIt')
  }

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

這樣對(duì)比就能明顯看出區(qū)別Promise實(shí)現(xiàn)的代碼邏輯復(fù)雜,不清晰,不直觀(guān),而通過(guò)async await,可以將異步邏輯,用類(lèi)似于同步的代碼實(shí)現(xiàn),簡(jiǎn)潔明了

這是到目前為止的個(gè)人理解,轉(zhuǎn)載請(qǐng)標(biāo)明出處

最后編輯于
?著作權(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)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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