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 的更优雅写法
相关推荐
Lee川2 小时前
探索JavaScript的秘密令牌:独一无二的`Symbol`数据类型
javascript·面试
Lee川2 小时前
深入浅出JavaScript事件机制:从捕获冒泡到事件委托
前端·javascript
恋猫de小郭2 小时前
Flutter 发布官方 Skills ,Flutter 在 AI 领域再添一助力
android·前端·flutter
心在飞扬2 小时前
工具调用出错捕获提升程序健壮性
前端·后端
HelloReader2 小时前
Tauri 命令作用域(Command Scopes)精细化控制你的应用权限
前端
心在飞扬2 小时前
基于工具调用的智能体设计与实现(*)
前端·后端
心在飞扬2 小时前
函数调用快速提取结构化数据使用技巧
前端·后端
心在飞扬2 小时前
不支持函数调用的大语言模型解决技巧
前端·后端
codingWhat2 小时前
如何实现一个「万能」的通用打印组件?
前端·javascript·vue.js