⭐ 推荐:社区规则条款 V1.0

js Promise 是什么怎么使用

满月居于空
满月居于空 版主萌新站长
发布于 2026-10-17 05:07 ·1 浏览 ·0 回复
内容摘要

Promise 是表示异步操作最终结果的对象,讲解其 pending、fulfilled、rejected 三态不可逆,then、catch、finally 的链式用法与 async/await 推荐写法,并说明 all、allSettle

Promise 是 JavaScript 中表示「一个尚未完成、但将来会有结果(成功或失败)的异步操作」的对象。它的核心价值是把层层嵌套的回调改写成链式调用:用 new Promise 创建,用 then/catch/finally 消费结果,日常开发里更推荐配合 async/await 写。

Promise 是什么?三个状态怎么理解

结论:Promise 只有三种状态——pending(进行中)、fulfilled(已成功)、rejected(已失败),状态一旦从 pending 变成 fulfilled 或 rejected,就永久固定、不可逆转。

const p = new Promise((resolve, reject) => {
  // 执行器函数是同步执行的
  setTimeout(() => resolve('ok'), 1000)
})
console.log(p) // Promise { <pending> }

注意两点:new Promise(executor) 里的 executor 是同步立即执行的,只有 resolve/reject 的结果才是异步交付;then 的回调属于微任务(microtask),会在当前同步代码和 setTimeout 之前执行。

console.log(1)
Promise.resolve().then(() => console.log(3))
setTimeout(() => console.log(4))
console.log(2)
// 输出顺序:1 2 3 4

Promise 怎么使用?基本写法

结论:用 then 拿成功值,用 catch 抓错误,链式调用中任意一环 return 的值都会成为下一个 then 的入参。

fetch('/api/user')
  .then(res => res.json())
  .then(data => {
    console.log(data.name)
    return fetch('/api/order')
  })
  .then(res => res.json())
  .catch(err => console.error('任一环节出错都会到这里:', err))
  .finally(() => console.log('无论成功失败都执行'))

关键点:catch 能捕获整条链上前面任意一环抛出的错误,所以链尾放一个 catch 就够了;如果 then 里 return 的是一个新的 Promise,链会等它完成再往下走,这就是「串行异步」的标准写法。

then、catch、finally 有什么区别

结论:then 接收成功和失败两个回调,catch(fn) 等价于 then(null, fn),finally 不接收参数、也不改变结果,只用于收尾。

finally 的返回值会被忽略(除非它返回一个 rejected 的 Promise),适合放 loading 关闭、连接释放这类清理逻辑。另外 then 的成功回调里 throw 的错误,不会传给同一个 then 的第二个参数,而是传给下一个 catch——这是新手最容易踩的坑。

Promise.all、allSettled、race、any 怎么选

结论:要全部成功用 Promise.all,要拿到全部结果(不管成败)用 Promise.allSettled,要最快返回用 Promise.race,要第一个成功用 Promise.any。

方法成功条件失败条件返回
Promise.all全部 fulfilled任一 rejected 就立刻 reject结果数组,顺序与传入一致
Promise.allSettled等全部结束不会 reject{status, value/reason} 数组
Promise.race第一个 settled第一个是 rejected 就 reject第一个结束的值
Promise.any第一个 fulfilled全部 rejected 才 reject(AggregateError)第一个成功的值

Promise.all 的返回顺序跟传入顺序一致,不是完成顺序,但它有一个特性要记住:只要有一个失败就立即 reject,其它 Promise 并不会被取消,仍在后台继续跑。

async/await 和 Promise 是什么关系

结论:async/await 是 Promise 的语法糖,async 函数一定返回 Promise,await 后面可以跟任意 thenable。

async function load() {
  try {
    const res = await fetch('/api/user')
    return await res.json()
  } catch (e) {
    console.error(e)
  }
}
load().then(data => console.log(data))

await 会让出执行权,但只暂停当前 async 函数的内部流程,不阻塞主线程。用 try/catch 代替 .catch() 时,要包住每一个可能抛错的 await。另外在 for 循环里 await 是串行执行,想并发就用 await Promise.all(list.map(...))。

常见坑与结论汇总

结论:Promise 的坑集中在「忘记 return」和「不处理 rejection」两处。

  • 在 .then 里忘记 return,下一个 then 拿到的是 undefined,异步也没被等待;
  • 没有 .catch 的 rejection 会触发 unhandledrejection 事件,Node.js 中可能导致进程退出;
  • Promise 一旦创建就会立即执行,无法取消,需要中断要自己用 AbortController 配合 fetch;
  • new Promise 里如果同步抛错,Promise 会变成 rejected,而不是向外抛出。

一句话收束:Promise 用三种不可逆状态统一了异步结果的表达,日常写法是 async/await + try/catch,并发场景按「全成功 / 全结束 / 最快 / 首个成功」四种需求分别选 all、allSettled、race、any,最需要警惕的是链中漏掉 return 和漏掉错误处理。

本文转载自 GJ站长论坛,原文地址:https://www.gj0.com/thread-2222.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 0

还没有回复,来抢沙发~