前端八股-promise

引言

在 JavaScript 里,Promise 是处理异步操作的一种对象,它代表着一个异步操作的最终完成(或失败)及其结果值。Promise 主要用于解决回调地狱问题,让异步代码的书写更具可读性和可维护性。下面为你介绍 Promise 的相关内容。

Promise 的三种状态

  • pending:初始状态,既不是成功也不是失败。
  • fulfilled:意味着操作成功完成。
  • rejected:表示操作失败。

Promise 的状态一旦从 pending 变为 fulfilled 或者 rejected,就不会再发生改变,会一直保持这个结果,这就是所谓的resolved(已定型)。

题目1

问题

javascript 复制代码
// This is a JavaScript Quiz from BFE.dev

console.log(1)
const promise = new Promise((resolve) => {
  console.log(2)
  resolve()
  console.log(3)
})

console.log(4)

promise.then(() => {
  console.log(5)
}).then(() => {
  console.log(6)
})

console.log(7)

setTimeout(() => {
  console.log(8)
}, 10)

setTimeout(() => {
  console.log(9)
}, 0)

结果

html 复制代码
1 (同步)
2 (Promise构造函数同步执行)
3 (Promise构造函数同步执行)
4 (同步)
7 (同步)
5 (微任务:第一个then)
6 (微任务:第二个then)
9 (宏任务:延迟0ms的setTimeout)
8 (宏任务:延迟10ms的setTimeout)

分析

这段代码涉及 JavaScript 的同步代码执行顺序 、Promise 微任务(microtask) 和定时器宏任务(macrotask) 的执行机制,JavaScript 是单线程的,代码会先按顺序执行同步任务 ,遇到异步任务会放入对应的任务队列,等待同步任务执行完毕后再先执行微任务,然后执行宏任务,并且Promise 构造函数中的回调是同步执行的:

题目二

问题

javascript 复制代码
// This is a JavaScript Quiz from BFE.dev

new Promise((resolve, reject) => {
  resolve(1)
  resolve(2)
  reject('error')
}).then((value) => {
  console.log(value)
}, (error) => {
  console.log('error')
})

结果

答案为1

分析

关键规则:状态一旦从 pending 变为 fulfilled 或 rejected,就会永久固定,后续再调用 resolve 或 reject 都无效。

javascript 复制代码
new Promise((resolve, reject) => {
  resolve(1);  // ① 首次调用,状态从 pending → fulfilled,值为 1
  resolve(2);  // ② 状态已固定为 fulfilled,此调用无效
  reject('error');  // ③ 状态已固定,此调用无效
}).then(
  (value) => { console.log(value); },  // 成功回调
  (error) => { console.log('error'); }  // 失败回调
)

题目三

问题

javascript 复制代码
// This is a JavaScript Quiz from BFE.dev

Promise.resolve(1)
.then(() => 2)
.then(3)
.then((value) => value * 3)
.then(Promise.resolve(4))
.then(console.log)

结果

这段代码的输出结果是 6

分析

.then() 期望接收一个回调函数 作为参数,如果传入的不是函数(如 then(3) 或 then(Promise.resolve(4))),会被自动忽略,并直接透传上一个 Promise 的结果值。

javascript 复制代码
Promise.resolve(1)                // 初始值为 1
.then(() => 2)                   // 返回 2 → 值变为 2
.then(3)                         // 3 不是函数,被忽略 → 值仍为 2
.then((value) => value * 3)      // 值 2 × 3 → 返回 6
.then(Promise.resolve(4))        // Promise.resolve(4) 不是函数,被忽略 → 值仍为 6
.then(console.log)               // 打印最终值 6

题目四

问题

javascript 复制代码
// This is a JavaScript Quiz from BFE.dev

Promise.resolve(1)
.then((val) => {
  console.log(val)
  return val + 1
}).then((val) => {
  console.log(val)
}).then((val) => {
  console.log(val)
  return Promise.resolve(3)
    .then((val) => {
      console.log(val)
    })
}).then((val) => {
  console.log(val)
  return Promise.reject(4)
}).catch((val) => {
  console.log(val)
}).finally((val) => {
  console.log(val)
  return 10
}).then((val) => {
  console.log(val)
})

结果

1 → 2 → undefined → 3 → undefined → 4 → undefined → undefined

分析

关键知识点

  1. .then() 中没有 return 时,默认返回 undefined。
  2. 嵌套的 Promise 会等待内部执行完毕,再将结果传递给外层。
  3. .catch() 捕获错误后,状态会转为 fulfilled,后续 .then() 会继续执行。
  4. .finally() 不接收参数,返回值无效,仅用于执行清理操作。
相关推荐
亿元程序员2 小时前
太牛了!这AI做出来的游戏,居然还能变现!
前端
hellice2 小时前
闪传 FlashDrop 实战:我用 300 行 Node 代码做了个「4 位取件码」临时文件中转站
前端·产品
用户0829773260052 小时前
RTX 5500 MIG 踩坑记录:切分之后模型跑不起来,排错整整一下午
前端
Lank_M3 小时前
AI 放大后的图更清楚,但它不能当原图入库
前端
Swot3 小时前
SvelteKit 数据流研究:`+page.js` 和 `+page.server.js` 到底谁在跑,数据又去了哪儿
前端·后端
用户4147679304153 小时前
Windows 触摸屏上 Swiper 轮播滑不动?可能是内部滚动容器抢走了你的手势
前端
张明君644513 小时前
从一个 Referer 引发的 403,到 SSR 服务失稳:Astro 流式渲染与缓存失效分析
前端
律宏阔3 小时前
微信小程序 + Taro + TDesign 去掉 [&&&],让普通 Tailwind 类接管局部样式
前端·微信小程序·taro
费曼学习法3 小时前
把 3 个内部服务封装成 MCP Server 的工程复盘:进程模型、超时与错误契约
前端
Captaincc3 小时前
转译:《软件工程师现在该怎么办》
前端·后端·ai编程