async/await的使用方法

1.async的基本形式和用法

首先看一個基本寫法:promise

async function demoFunc () {
  return new Promise((resolve,  reject) => {
    resolve('hello world')
  })
}

async 寫在函數前,返回一個Promise對象async

  • 當返回值不是一個promise對象時,會被強轉成promise對象
async function asyncFunc () {
  return 'hello world'
}

經過控制檯 能夠看到,返回了一個Promise
image.png函數

2.await

await操做只能用在async函數中,不然會報錯。spa

arg = await awaitFunc

awaitFunc能夠是任何值,一般是一個promise3d

3.async和await基本使用

寫一個函數,返回promise對象,該函數會在2s後輸出參數信息code

function printName(name) {
  return new Promise((resolve, reject) => {
      setTimeout(() => {
          resolve(name)
      }, 2000)
  } )
}

而後再寫一個async函數,此時就能夠用上咱們的await關鍵字,由於await後一般放的是一個promise對象,因此能夠寫上以上的調用對象

async function getName() {
  let name = await printName('jack')
  console.log('hello ', name)
}
getName() // 2s後 輸出hello jack

代碼的執行過程是調用了getName方法,遇到了await,await表示代碼在這裏暫停了,再也不向下執行,等待promise對象執行完畢,拿到promise resolve的值並返回後,再繼續向下執行。blog

  • 若此時promise對象拋出了錯誤呢?

咱們能夠用try catchget

function printName(name) {
  return new Promise((resolve, reject) => {
      setTimeout(() => {
          throw new Error('出錯了') // 模擬報錯
          resolve(name)
      }, 2000)
  } )
}
async function getName () {
  try {
    let name = await printName('jack')
    console.log('hello ', name)
  } catch (err) {
    console.log(err, ' 被catch抓到啦')
  }
}
getName() // 控制檯輸出 出錯了 被catch抓到啦

也可使用promise的.then() .catch()表達式,等價爲同步

function printName(name) {
  return new Promise((resolve, reject) => {
      setTimeout(() => {
          throw new Error('出錯了') // 模擬報錯
          resolve(name)
      }, 2000)
  } )
}
async function getName () {
    let name = await printName('jack')
    return name
}
// 由於在最前面咱們就知道,async返回的是一個promise對象,此處的getName其實也就是一個promise對象
getName().then((name)=> {
    console.log('hello ', name)
}).catch((err) => {
    console.log(err, ' 被catch抓到啦')
}) // 會進入catch

目前看不出咱們的async和await有什麼妙用。讓咱們來多寫幾個,妙用初體驗

async function getName() {
  let name1 = await printName('Jack')
  let name2 = await printName('Bob')
  let name3 = await printName('Cindy')
  console.log('hello ', name1, ' ', name2, ' ', name3)
}
getName() // 6s後輸出 hello Jack Bob Cindy

有沒有感受本身在寫正常的同步代碼了?爽嗎?還能夠更爽,咱們繼續看例子
如今要求使用promise寫一個函數,要求第一步消耗1秒,第二步消耗2秒,第三步消耗3秒,總時間是1+2+3一共6秒,咱們看看promise的鏈式寫法

function getTime(n) {
    return new Promise(resolve => {
        setTimeout(() => resolve(n + 1000), n)
    })
}

function step1(n) {
    console.log(`步驟1消耗${n}秒`)
    return getTime(n)
}

function step2(n) {
    console.log(`步驟2消耗${n}秒`)
    return getTime(n)
}

function step3(n) {
    console.log(`步驟3消耗${n}秒}`)
    return getTime(n)
}
// promise鏈式寫法
function doThis() {
    const time1 = 1000
    step1(time1)
        .then(time2 => step2(time2))
        .then(time3 => step3(time3))
        .then(retult => {
            console.log('retult is 'retult)
        })
}
// async函數寫法
async function doThis() {
    const time1 = 1000
    const time2 = await step1(time1)
    const time3 = await step2(time2)
    const result = await step3(time3)
    console.log(`result is ${result}`)
}
doThis()

看看運行結果,輸出的時間間隔能夠感覺到是1秒,2秒,3秒
image.png

有沒有感受不用跟繁瑣的鏈式打交道了。其實需求一變的話,會更明顯。若是咱們需求第一步 第二步 第三步分佈別爲1秒2秒3秒不變。追加需求,第二步須要加上第一步的時間,第三步要加第二步的時間,即第一步1秒,第二步1+2=3秒,第三步3+3=6秒,一共9秒,咱們先看看鏈式寫法

function step1(n) {
    console.log(`步驟1消耗${n}秒`)
    return getTime(n);
}

function step2(m, n) {
    console.log(`步驟2消耗${m} and ${n}秒`);
    return getTime(n);
}

function step3(k, m, n) {
    console.log(`步驟3消耗${k}, ${m} and ${n}秒`)
    return getTime(k + m + n);
}
// Promise方式調用
function doThis() {
    const time1 = 1000
    step1(time1)
        .then(time2 => {
            return step2(time1, time2)
                .then(time3 => [time1, time2, time3]);
        })
        .then(times => {
            const [time1, time2, time3] = times;
            return step3(time1, time2, time3);
        })
        .then(result => {
            console.log(`result is ${result}`)
        });
}

// async/await方式調用
async function doThis() {
    const time1 = 1000
    const time2 = await step1(time1)
    const time3 = await step2(time1, time2)
    const result = await step3(time1, time2, time3)
    console.log(`result is ${result}`)
}

image.png
能夠明顯感受到輸出間隔1秒 3秒 6秒
最後輸出7是由於咱們的6在step3內getTime(6000)加1000ms變成7000

這個時候感受到async/await的便捷之處了嗎?除了寫法方便,不知道你們發現了沒,咱們的參數能夠直接調用...改天補充,有急事

相關文章
相關標籤/搜索