async/await和Promise的区别?

0 阅读3分钟

一、Promise 是什么

PromiseES6 提供的用于处理异步操作的对象

它有三种状态:

pending   (进行中)
fulfilled (成功)
rejected  (失败)

基本写法:

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("成功")
  }, 1000)
})

promise
  .then(res => {
    console.log(res)
  })
  .catch(err => {
    console.log(err)
  })

特点:

  • 通过 .then() 处理成功
  • 通过 .catch() 处理错误
  • 可以 链式调用

二、async / await 是什么

async/awaitES2017 提出的异步写法,是基于 Promise 的语法糖。

特点:

  • async 声明函数为异步函数
  • await 等待 Promise 返回结果
  • 写起来像同步代码

例子:

async function getData() {
  const res = await fetch("/api/data")
  const data = await res.json()
  console.log(data)
}

三、核心区别

对比点Promiseasync/await
写法链式调用同步风格
可读性一般更好
错误处理.catch()try...catch
调试不太友好更像同步代码
本质原生异步对象Promise 的语法糖

四、代码对比

Promise 写法

function getUser() {
  return fetch("/user")
    .then(res => res.json())
    .then(data => {
      console.log(data)
      return fetch("/order")
    })
    .then(res => res.json())
    .then(order => {
      console.log(order)
    })
    .catch(err => {
      console.log(err)
    })
}

问题:

.then 链式调用太多
代码可读性差

async/await 写法

async function getUser() {
  try {
    const res = await fetch("/user")
    const user = await res.json()

    const res2 = await fetch("/order")
    const order = await res2.json()

    console.log(user, order)
  } catch (err) {
    console.log(err)
  }
}

优点:

逻辑清晰
更像同步代码
更容易维护

五、async/await 的本质

其实:

async function test() {
  return 1
}

等价于:

function test() {
  return Promise.resolve(1)
}

所以:

async函数一定返回Promise

六、await 的作用

await 只能等待 Promise 对象

例如:

const data = await fetch("/api")

等价于:

fetch("/api").then(res => ...)

七、async/await 的限制

1 必须在 async 函数里

错误写法:

const data = await fetch("/api")

正确:

async function getData() {
  const data = await fetch("/api")
}

2 默认是串行执行

const a = await getA()
const b = await getB()

执行顺序:

getA → 完成 → getB

有时候会变慢。


八、并发优化(重要)

如果两个请求 互不依赖

错误写法:

const a = await getA()
const b = await getB()

优化写法:

const [a, b] = await Promise.all([
  getA(),
  getB()
])

这样会 并发执行


九、什么时候用 Promise?

适合:

  • 并发请求
  • 多个异步任务组合
  • Promise.all
  • Promise.race

例如:

Promise.all([api1(), api2(), api3()])

十、什么时候用 async/await?

适合:

  • 顺序执行
  • 复杂逻辑
  • try/catch 错误处理
  • 提高代码可读性

例如:

async function init() {
  const user = await getUser()
  const order = await getOrder(user.id)
}

十一、面试标准回答

可以这样说:

Promise 是 ES6 提供的用于处理异步操作的对象,通过 then 和 catch 进行链式调用。
async/await 是 ES2017 提供的语法,是 Promise 的语法糖,可以让异步代码写起来像同步代码,提高可读性。
async 函数会返回一个 Promise,await 用来等待 Promise 的结果。
在实际开发中,如果是复杂逻辑或者顺序执行,一般使用 async/await;如果是多个异步任务并发执行,通常配合 Promise.all 使用。


十二、再给你一个高级面试点(很多人不会)

很多人不知道:

await 123

也是合法的。

因为 JS 会自动变成:

await Promise.resolve(123)

最后总结

一句话记住:

Promise → 异步机制
async/awaitPromise 的更优雅写法