在面试中,经常会遇到一些 考察 JavaScript 异步执行顺序 的 Promise 输出题。这类题目乍一看令人眼花缭乱,但只要掌握了核心知识点,就能轻松搞定。
本文将结合 BFE.dev 上的五道 Promise 面试题,从原理入手,带你逐一拆解,彻底掌握这类题的解法套路。

一、这类面试题到底在考什么?
这些题目主要考察你对 JavaScript 异步执行模型的理解,尤其是以下几点:
- 同步任务 vs 异步任务 的执行顺序
- 微任务(microtask) vs 宏任务(macrotask)
- Promise 的执行流程(executor、then、catch、finally)
then
的参数处理逻辑(如传入非函数)resolve(promise)
和嵌套 Promise 的行为
掌握这几点,Promise 输出题将不再是难题。
二、题目详解
题目 1:Promise 执行顺序基础题
scss
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)
解题思路:
- 同步代码立即执行。
new Promise()
中的 executor 是同步执行的。then
添加的是 微任务,排在本轮事件循环结束后。setTimeout
是 宏任务,排在下一轮事件循环。
执行顺序:
console.log(1)
✅- 进入
new Promise
,输出2
和3
- 输出
4
- 注册了两个
then
(微任务) - 输出
7
- 微任务执行:输出
5
,然后6
- 执行
setTimeout 0
(宏任务):输出9
- 执行
setTimeout 10
:输出8
输出结果:
1
2
3
4
7
5
6
9
8
题目 2:Promise resolve 多次是否生效?
javascript
new Promise((resolve, reject) => {
resolve(1)
resolve(2)
reject('error')
}).then((value) => {
console.log(value)
}, (error) => {
console.log('error')
})
解题思路:
- Promise 状态一旦确定(resolved/rejected)就不可更改。
- 只有第一次
resolve(1)
生效。
输出结果:
1
题目 3:then 中参数不是函数会怎样?
javascript
Promise.resolve(1)
.then(() => 2)
.then(3)
.then((value) => value * 3)
.then(Promise.resolve(4))
.then(console.log)
解题思路:
then(3)
不是函数,相当于then(undefined)
,会将上一个值传下去。then(Promise.resolve(4))
会 立即执行Promise.resolve(4)
,但它不是函数,不会当作 callback 使用 ,所以和then(undefined)
效果一样。- 整体变为:
javascript
Promise.resolve(1)
.then(() => 2) // => 2
.then(undefined) // => 2
.then((v) => v * 3) // => 6
.then(undefined) // => 6
.then(console.log) // 输出 6
输出结果:
6
题目 4:链式 Promise + 异常处理
javascript
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
→ 打印2
undefined
传给下一个 → 打印undefined
return Promise.resolve(3).then(...)
,里面打印3
- 上个 then 没返回值(隐式
undefined
)→ 打印undefined
- 抛出
Promise.reject(4)
→ 进入catch
打印4
finally
不会影响值传递,仍是undefined
→ 打印undefined
- 打印
undefined
输出结果:
javascript
1
2
undefined
3
undefined
4
undefined
undefined
题目 5:resolve(promise) 的行为
javascript
const promise = new Promise((resolve, reject) => {
const promise2 = Promise.reject('error').then(() => {
console.log(1)
}, () => {
console.log(2)
})
resolve(promise2)
});
promise.then(console.log);
解题思路:
promise2
是一个 rejected Promise,但有then
捕获了错误并打印2
,并返回一个 fulfilled 的 Promise。- 外层
resolve(promise2)
,会等promise2
的状态。 - 所以最终
promise.then(...)
是 resolved 状态,值为undefined
(因为promise2
的 then 没返回值)
输出结果:
javascript
2
undefined
三、总结:拿下 Promise 输出题的 3 个关键点
-
掌握事件循环模型:同步任务、微任务、宏任务的执行顺序。
-
理解 Promise 的本质:状态不可变、then 传值规则。
-
特殊情况要牢记:
then(非函数)
会被忽略,直接传值。resolve(promise)
会等待内部状态。finally()
不影响链的值传递。
结语
Promise 输出类题目本质不难,关键是理解执行机制。多刷题、多总结,做到心中有序,你也能在面试中游刃有余。
如果你觉得本文有帮助,欢迎点赞收藏关注。