async/await和Promise的区别?

一、Promise 是什么

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

它有三种状态:

scss 复制代码
pending   (进行中)
fulfilled (成功)
rejected  (失败)

基本写法:

typescript 复制代码
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 返回结果
  • 写起来像同步代码

例子:

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

三、核心区别

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

四、代码对比

Promise 写法

javascript 复制代码
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 写法

javascript 复制代码
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 的本质

其实:

csharp 复制代码
async function test() {
  return 1
}

等价于:

javascript 复制代码
function test() {
  return Promise.resolve(1)
}

所以:

javascript 复制代码
async函数一定返回Promise

六、await 的作用

await 只能等待 Promise 对象

例如:

csharp 复制代码
const data = await fetch("/api")

等价于:

scss 复制代码
fetch("/api").then(res => ...)

七、async/await 的限制

1 必须在 async 函数里

错误写法:

csharp 复制代码
const data = await fetch("/api")

正确:

csharp 复制代码
async function getData() {
  const data = await fetch("/api")
}

2 默认是串行执行

csharp 复制代码
const a = await getA()
const b = await getB()

执行顺序:

复制代码
getA → 完成 → getB

有时候会变慢。


八、并发优化(重要)

如果两个请求 互不依赖

错误写法:

csharp 复制代码
const a = await getA()
const b = await getB()

优化写法:

scss 复制代码
const [a, b] = await Promise.all([
  getA(),
  getB()
])

这样会 并发执行


九、什么时候用 Promise?

适合:

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

例如:

scss 复制代码
Promise.all([api1(), api2(), api3()])

十、什么时候用 async/await?

适合:

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

例如:

csharp 复制代码
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 使用。


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

很多人不知道:

csharp 复制代码
await 123

也是合法的。

因为 JS 会自动变成:

javascript 复制代码
await Promise.resolve(123)

最后总结

一句话记住:

javascript 复制代码
Promise → 异步机制
async/await → Promise 的更优雅写法
相关推荐
梦想平凡25 分钟前
百游棋牌源代码开发搭建教程(十):隔离部署、备份恢复与双端验收
java·前端·javascript·数据库·源代码管理
yume_sibai2 小时前
06-Rust Web 开发实战(Axum 框架 + 数据库 + JWT 认证 + 中间件 + 部署)
前端·数据库·rust
计算机魔术师3 小时前
特朗普上台打给黄仁勋:AI末日论是骗局,我们绝不让它发生
前端
troy1283 小时前
Python 基础语法(八):Web 后端开发、数据分析与可视化、网络爬虫、人工智能 / 大模型应用
前端·python·数据分析
计算机魔术师3 小时前
CEO说要慢下来,黑客说别做梦了——同一篇论文,两种命运
前端
kyriewen4 小时前
我花3天抓了一个幽灵bug,凶手藏在第4层
前端·javascript·程序员
IT_陈寒4 小时前
Java里用Stream.parallel()翻车实录,这性能还不如单线程
前端·人工智能·后端
wangchunyu1145 小时前
JavaScript 零基础入门教程
前端
hanchenxing5 小时前
前端异步任务三方案:Celery vs Redis Stream vs BullMQ 实战对比消息队列
前端·数据库·redis·异步任务·方案对比
mONESY6 小时前
LangGraph.js 从零上手:把 Agent 工作流从一条线变成一张网
javascript