小白回顧記錄async await

async、await是promise的語法糖,使用async和await,可讓異步代碼的書寫像同步代碼同樣。promise

async關鍵字

將async關鍵字放在一個普通的function前面,會變成async function,那麼async function和普通的function有什麼不同呢?異步

function hello() {
  return 'hello'
}
hello()
// "hello"
async function hello() {
  return 'hello'
}
hello()
// Promise {<fulfilled>: "hello"}

從上面的列子能夠看出來,當在function 前面加上async後,該函數就會返回一個promise。
異步函數的特徵之一就是保證函數的返回值是promiseasync

由於async function的返回值是一個promise,要使用promise完成時的返回值,能夠經過.then()進行獲取函數

async function hello() {
  return 'hello'
}
hello().then((str) => alert(str))

await關鍵字

await關鍵字須要和async關鍵字配合使用,也只能在異步函數中才會起做用。await能夠放在任何異步的,基於promise的函數以前,它會阻塞代碼的執行,知道promise完成,而後返回返回結果值。code

async function hello() {
  return new Promise((resolve) => {
    setTimeout(() => {resolve('hello')}, 1000);
  });
}

async function sayHello() {
  await hello();
  alert('done!')
}

sayHello();
// Promise {<pending>}

1s後會彈出「done!」ip

一些容易出問題的點

Q1:上面說到await會阻塞程序運行,直到異步函數hello()執行出結果,那麼若是hello執行的結果是reject或者因爲一些問題throw new Error()的話,await後面的代碼還會執行嗎?
答案:不能執行。get

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

async function sayHello() {
  await hello();
  alert('done!')
}

sayHello();
// Promise {<rejected>: "hello"}
async function hello() {
  return new Promise((resolve, reject) => {
    throw new Error('hello');
  });
}

async function sayHello() {
  await hello();
  alert('done!')
}

sayHello();
// Promise {<rejected>: Error: hello
    at <anonymous>:3:11
    at new Promise (<anonymous>)
    at hello (<anonymous>:2:1…}

這兩個狀況下都不會在執行 alert('done!');同步

若是咱們但願hello()運行中執行了reject或者是拋出錯誤後,不影響後面alert('hello')的執行應該怎麼辦?增長try catch就行it

async function sayHello() {
  try {
    await hello();
  } catch (e) {
    console.log(e)
  }
  alert('done!')
}

Q2:reject或者throw new error的捕獲會繼續向下傳遞嗎?
答案:會,reject和error會一直冒泡出去io

async function hello() {
  return new Promise((resolve, reject) => {
    throw new Error('hello');
  });
}

async function sayHello() {
  await hello();
  alert('done!')
}

sayHello().then((res) => {alert(res), (rej)=>{alert(rej)}})
// Promise {<fulfilled>: undefined}

窗口會彈出「Error: hello」,reject同理,輸出「hello」

async function hello() {
  return new Promise((resolve, reject) => {
    throw new Error('hello');
  });
}

async function sayHello() {
  await hello();
  alert('done!')
}
async function catchFunc() {
  try {
    await sayHello()
  } catch(e) {
    alert(e)
  }
}
catchFunc()
// Promise {<fulfilled>: undefined}

窗口會彈出「Error: hello」,reject同理,輸出「hello」

Q3:下面兩段代碼有什麼區別
代碼片斷1

async function hello() {
  return new Promise((resolve, reject) => {
    throw new Error('hello');
  });
}

async function sayHello() {
  await hello();
  alert('done!')
}
async function catchFunc() {
  try {
    sayHello()
  } catch(e) {
    alert(e)
  }
}

catchFunc()
// Promise {<fulfilled>: undefined}

代碼片斷2:

async function hello() {
  return new Promise((resolve, reject) => {
    throw new Error('hello');
  });
}

async function sayHello() {
  await hello();
  alert('done!')
}
async function catchFunc() {
  try {
    await sayHello()
  } catch(e) {
    alert(e)
  }
}
catchFunc()
// Promise {<fulfilled>: undefined}

答案:代碼片斷2會彈出「Error:hello」,代碼片斷1不會。分析的緣由應該是代碼片斷2是在sayHello函數執行完後進行捕獲錯誤,因此能夠捕獲到錯誤,代碼片斷1沒有使用await,捕獲錯誤的時候函數sayHello異步執行還沒報錯,因此不會捕獲到。

未完待續...
既然async/await是promise的語法糖,兩者怎麼轉換呢?

async await MDN

相關文章
相關標籤/搜索