Question 1(基础概念)

中文: 请你解释一下什么是 Promise?它主要解决了什么问题?

English: Can you explain what a Promise is and what problem it is designed to solve?

 

标准答案(中文)

Promise 是一个用于表示异步操作结果的对象,它本质是一个状态机 + 回调容器 它代表一个未来会完成(或失败)的操作结果

Promise 主要解决的是:

  1. 回调地狱(callback hell)问题
  2. 让异步代码更加清晰、可读、可维护
  3. 提供统一的错误处理机制

Promise 有三种状态:

一旦状态从 pending 变为 fulfilled 或 rejected,就不可再改变(状态不可逆)

作用:Promise能够让你不用关心任务什么时候结束(因为用到Promise的地方,可能都会有异步操作),在new的时候告诉它执行什么任务,之后只需要通过 then 告诉它“之前的任务结束之后该干嘛”。

 

面试加分点:Promise 本质上是一个状态机,并且它的回调(then/catch)是放入微任务队列执行的。

 

Standard Answer (English)

A Promise is an object representing the result of an asynchronous operation, essentially a state machine + callback container. It represents the eventual completion or failure of an operation and its resulting value.

A Promise mainly solves:

  1. The problem of callback hell
  2. Makes asynchronous code more readable and maintainable
  3. Provides a unified error handling mechanism

A Promise has three states:

Once the state changes from pending to fulfilled or rejected, it becomes immutable (cannot be changed again).

 

面试加分点:A Promise is essentially a state machine, and its callbacks (then/catch) are executed in the microtask queue.

Question 2(基础 + 原理)

中文: Promise 的 then 方法返回的是什么?为什么可以链式调用?

English: What does the then method return, and why can Promises be chained?

 

标准答案(中文)

then 方法一定会返回一个新的 Promise 对象

之所以可以链式调用,是因为:

具体规则:

  1. 如果 then 里返回的是一个普通值: → 会被包装成 Promise.resolve(value)
  2. 如果返回的是一个 Promise: → 下一个 then 会等待这个 Promise 结果
  3. 如果抛出错误: → 会变成 Promise.reject(error),进入 catch

面试加分点:

then 的链式调用本质是“值的穿透 + Promise 的扁平化(flattening)”。

 

Standard Answer (English)

The then method always returns a new Promise.

Chaining works because:

Rules:

  1. If a normal value is returned: → It becomes Promise.resolve(value)
  2. If a Promise is returned: → The next then waits for it
  3. If an error is thrown: → It becomes Promise.reject(error) and goes to catch

面试加分点:

Promise chaining is essentially value propagation + Promise flattening.

 

举个面试常用例子

你可以这样解释:

中文:

English:

 

Question 3(进阶 / 高频)

中文: then 的两个参数(onFulfilled, onRejected)和 catch 有什么区别?为什么通常不推荐在 then 里写第二个参数?

English: What is the difference between the two arguments of then (onFulfilled, onRejected) and catch? Why is it usually not recommended to use the second argument of then?

参考:https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Async_JS/Promises#catching_errors

分析:

推荐写法:


中文回答: then 的两个参数(onFulfilled, onRejected)和 catch 有什么区别?

then(onFulfilled, onRejected) 和 .catch(onRejected) 功能相关,但有重要区别:

最关键的区别在于错误捕获范围:

推荐写法: 成功用 .then(),错误统一用 .catch(),代码更清晰,可读性更好。

 

中文回答:为什么不推荐用 then 的第二个参数?

因为它:

  1. 不能捕获 then 内部抛出的错误
  2. 会导致错误处理逻辑分散
  3. 不符合链式错误处理的设计(error bubbling)

推荐统一使用 catch 来处理错误,使代码更清晰、可维护。

 

面试加分: Promise 的错误是“冒泡”的,应该在链的末尾统一用 catch 处理。


Standard Answer (English)

then(onFulfilled, onRejected) and .catch(onRejected) are related but have key differences:

The most important difference is error handling scope:

Best practice: Use .then() only for success, and chain .catch() for error handling. It improves readability and reduces bugs.

 

Why not use the second argument of then?

English:

It is not recommended because:

  1. It cannot catch errors thrown inside then
  2. It leads to scattered error handling
  3. It breaks the error propagation chain

Using catch provides a more consistent and maintainable error handling pattern.

 

面试加分:

Errors in Promises bubble down the chain and should be handled at the end using catch.

Question 4(重要)

中文: 如果在 then 里不写 return,会发生什么?值是怎么传递的?

English: What happens if you don’t return anything inside a then? How is the value propagated?

 

这个问题我感觉很陌生

Promise的then方法,我记得最多只用了一层,就是获取数据之后的处理,没有仔细的研究过then的链式用法。一般这种情况我会使用async...await方法来处理需要从前一个异步操作获取数据的场景。

一般来说,我是这样做的:

好像连new Promise定义promise过程都没有用到。所以最多使用只有一层then的调用。

如果是一个接口请求需要前一个接口的返回结果,我一般是这么写的:

这样做其实是对的,因为相对于多个then方法,async...await有以下好处:

但是必须要理解then的原理,因为老项目或者面试的时候肯定会问到:

必须懂 then 链式的理由

then的用法

实际开发中,几乎不用 then 的第二个参数,统一用 .catch() 捕获所有错误,更清晰。

then() 会返回新的 Promise,所以可以无限链式写多个 then,按顺序执行异步任务:

链式规则:

  1. thenreturn 普通值,会直接传给下一个 then
  2. thenreturn 新 Promise,下一个 then 会等待这个 Promise 完成
  3. 任何一步报错,都会直接跳到最后的 catch

return到底是哪里的return呢?

then函数里面,有两个函数参数,return应该写在哪里呢?

所以

日常开发只用 then(成功回调).catch(失败),很少用 then 第二个参数。使用catch来捕捉错误即可。

标准答案(中文)

如果在 then 里面不写 return,那么:

👉 默认会返回 undefined 👉 等价于:return undefined

并且这个 undefined 会被自动包装成:

然后传递给下一个 then

 

面试加分:

then 的返回值决定了下一个 then 的输入,如果不写 return,默认就是 undefined。


Standard Answer (English)

If you don’t return anything inside a then:

👉 It implicitly returns undefined 👉 Equivalent to: return undefined

This undefined is wrapped as:

and passed to the next then.

 

面试加分:

The return value of then determines the input of the next then. If omitted, it defaults to undefined.


几个例子,看返回值是什么?

例子1:

输出是什么?

为什么?

中文:

English:

例子2:

等价于:

返回了123

 

例子3:

⚠️ 注意!!!

这里没有 return,所以下一个 then 仍然拿到 undefined

 

 

Question 5(核心机制)

中文: Promise.resolve() 和 new Promise(resolve => resolve()) 有什么区别?

English: What is the difference between Promise.resolve() and new Promise(resolve => resolve())?

 

这一题已经进入Promise + 事件循环(event loop)核心考点了。

 

标准答案(中文)

Promise.resolve()new Promise(resolve => resolve()) 都会返回一个已解决(fulfilled)的 Promise,但它们在执行时机行为细节上是有区别的。

执行时机:

行为细节:

Promise.resolve自动“展开”(flatten)Promise

如果你给 Promise.resolve(xxx) 传的 xxx 本身就是一个 Promise,它不会包一层 Promise 再套一层,而是直接 “拆开”,等待内部那个 Promise 执行完,直接用它的结果。

这就叫 flatten / 展开 / 扁平化


Standard Answer (English)

Both Promise.resolve() and new Promise(resolve => resolve()) return a fulfilled Promise, but they differ in execution timing and behavior details.

execution timing:

behavior details:

Promise.resolve will unwrap nested Promises (flattening)


分析:

1、执行时机:

输出顺序:

为什么?

中文解释:

执行顺序:

  1. 同步代码先执行 → start
  2. 执行 new Promise → 重点:因为里面是同步 → 所以打印 new Promise
  3. resolve 后,把 then 放入微任务队列
  4. 执行 end
  5. 最后执行微任务 → then

English explanation:

  1. Run sync code → start
  2. Execute new Promise → executor runs immediately → new Promise
  3. then callback goes to microtask queue
  4. Run end
  5. Run microtask → then

2、行为细节

输出:1

 

Question 6(事件循环 / 高频)

中文: 下面代码的输出顺序是什么?请解释原因。

English: What is the output order of the following code? Explain why.

 

我的答案是:1,3,4,2。因为我知道setTimeout绝对是延时执行的,即使延迟时间是0。但是最终答案是1,4,3,2。

分析:

👉 同步代码,直接执行 输出:1


👉 宏任务(macrotask),放入任务队列(task queue) (不会立刻执行)


👉 微任务(microtask),放入微任务队列(microtask queue)


👉 同步代码,直接执行 输出:4


到这里为止(同步执行结束)

当前输出:


接下来执行队列

规则(面试必背):

中文: 每一轮事件循环: 👉 先清空所有微任务 👉 再执行一个宏任务


执行微任务:

输出:


再执行宏任务(setTimeout):

输出:


最终结果

 

英文 Explanation:

  1. Synchronous code runs first:

    • 1
    • 4
  2. Then microtasks:

    • 3 (from Promise)
  3. Then macrotasks:

    • 2 (from setTimeout)

Promise 的 then 属于微任务,会在当前同步代码执行完之后、下一个宏任务之前执行。

Promise callbacks (then) are microtasks, executed after synchronous code but before macrotasks.


Key Rule:

Microtasks always run before macrotasks

 

 

Question 7(执行顺序 / 进阶)

中文: 下面代码输出什么?

English: What is the output?

 

我的答案:start, end, promise1, promise2, timeout。回答正确。

分析:

1、第一阶段:同步代码

输出:


👉 宏任务,进入 task queue(暂不执行)


👉 这里很关键:

⚠️ 为什么? 因为第二个 then 要等第一个执行完才会加入队列


输出:


2、第二阶段:执行微任务

当前微任务队列:

执行:

👉 执行完后:


继续执行微任务:


3、第三阶段:执行宏任务


核心考点

关键点 1

then 是“链式微任务”

中文: 后一个 then 要等前一个执行完才会进入微任务队列

English: Each then in a chain is scheduled only after the previous one resolves


关键点 2

微任务队列是“清空执行”的

中文: 一旦开始执行微任务,会一直执行直到队列清空

English: The microtask queue is fully drained before moving to macrotasks


面试加分句:

中文: Promise 的 then 是按链式依赖逐个进入微任务队列,而不是一次性全部进入。

English: Promise then callbacks are queued sequentially based on resolution, not all at once.

 

 

Question 8(执行顺序 / 困难)

中文: 下面代码输出什么?

English: What is the output?

 

我的答案:A, B ,C。正确答案是A, C, B。

关键点是:多个 Promise 链之间的微任务是“交替执行”的,不是一个链跑完再跑另一个。

分析:

第一步:同步阶段

所有 Promise 创建完成


第二步:初始化微任务队列

此时微任务队列是:


第三步:执行第一个微任务(A)

输出:


⚠️ 关键点来了!!!

这里返回了:

👉 所以:


此时队列变成:


第四步:执行 thenC

输出:


第五步:执行 then(B)

输出:

 

Key idea:

Microtasks from different Promise chains are interleaved, not executed chain-by-chain.

中文: 当 then 返回一个 Promise 时,后续 then 会被“延迟”,让其他微任务有机会先执行。

English: When a then returns a Promise, the next then is deferred, allowing other microtasks to run first.

 

 

Question 9(执行顺序 / 难 / 综合)

中文: 下面代码输出什么?

English: What is the output?

 

我的答案:start, end, promise2, timeout1, promise1, timeout2。回答正确。

分析,这题涉及:

1、第一轮(主线程 / 主宏任务)

执行同步代码:

当前输出:

当前队列状态:


清空微任务队列

执行:

输出:


同时执行:

👉 加入宏任务队列


此时队列:


2、第二轮(执行宏任务 timeout1)

输出:


timeout1 内部:

👉 加入微任务队列


清空微任务队列

执行:


3、第三轮(执行宏任务 timeout2)

 

Key points:

  1. 微任务优先级高于宏任务

Microtasks run before macrotasks


  1. 每一轮宏任务执行完都会清空微任务

Each macrotask is followed by draining all microtasks


  1. 宏任务是按顺序进入队列的(FIFO)

Macrotasks are queued in order

 

中文: 事件循环是按“宏任务 → 清空微任务 → 下一个宏任务”的顺序执行的,微任务可以在执行过程中不断插入。

English: The event loop runs as: macrotask → drain microtasks → next macrotask. Microtasks can be dynamically added during execution.

 

Question 10(本质,这个了解即可,因为涉及到Generator迭代器)

中文: async/await 和 Promise 的关系是什么?本质上是怎么实现的?

English: What is the relationship between async/await and Promise? How does it work under the hood?

 

我的回答:async/await 是 promise的语法糖,async/await可以使用同步的方式来写异步代码。怎么实现不知道。

下面看答案:

标准答案(中文)

async/await 本质上是 Promise 的语法糖,它让我们可以用同步的写法来表达异步逻辑

在底层实现上:

  1. async 函数一定返回一个 Promise
  2. await 会把后面的表达式转成 Promise(相当于 Promise.resolve()
  3. await暂停函数执行,把后面的代码放入微任务队列
  4. 等 Promise resolve 后,再恢复执行(类似 .then

Standard Answer (English)

async/await is essentially syntactic sugar over Promises, allowing asynchronous code to be written in a synchronous style.

Under the hood:

  1. An async function always returns a Promise
  2. await converts the expression into a Promise (like Promise.resolve())
  3. await pauses execution and schedules the rest as a microtask
  4. Once resolved, execution resumes (similar to .then)

 

简化的答案:

中文:

async/await 是 Promise 的语法糖,async 函数返回 Promise,await 会把表达式转为 Promise 并暂停执行,把后续代码放入微任务队列,本质上等价于 Promise.then 的链式调用。

English:

Async/await is syntactic sugar over Promises. Async functions return Promises, and await converts expressions into Promises and resumes execution via microtasks, essentially behaving like chained .then calls.


分析:

async/await 写法:

本质等价于:


深度解析:

await 做了什么?

本质可以理解为:

 

关键机制(非常重要)

为什么说它“暂停”?

中文:

English:


常见追问:

Q:await 后面如果不是 Promise 会怎样?

👉 等价于:

 

Q:async 函数 return 什么?

👉 实际返回:

 

 

Question 11(Promise.all)

中文: 请你实现一个 Promise.all,并说明它的行为。

English: Implement Promise.all and explain how it works.

 

常见题目要求(面试官常说的话):

需要满足:

  1. 所有 Promise 成功 → 返回结果数组(按顺序)
  2. 有一个失败 → 立即 reject
  3. 支持普通值(不是 Promise)
  4. 结果顺序必须和输入一致(重点)

分析:

英文版:

 

简单回答:

“手写 Promise.all 的核心难点有两个:一是用计数器判断所有完成,二是必须按索引存放结果来保证顺序。我会用 Promise.resolve() 来兼容普通值,同时任何一个 reject 都会立刻终止。”

The core idea of Promise.all:

  1. Use an array to store results in order
  2. Use a counter to track completion
  3. Use Promise.resolve to normalize inputs
  4. Resolve when all succeed
  5. Reject immediately on any failure
  6. Handle empty array case

 

代码:

我的一个疑问点:

这个代码里面,为什么第一个判断里面reject,需要使用return,直接reject不行吗?还有 len === 0时的判断,为什么需要return,直接resolve([]) 不行吗?

 

因为我没有搞清楚resolve和reject的作用,我以为resolve和reject执行之后,后面的代码就不会执行了。不是的,resolve或者reject之后,只是promise的状态确定了,但是里面的代码还是会继续执行下去,如果promises参数都不是数组,那么promises.forEach肯定报错。所以必须使用return来停止代码的执行。

所以说概念很多,需要不断的分辨清楚。

 

Question 12(Promise.race)

中文

请你实现一个 Promise.race

English

Implement Promise.race

 

题目要求:

需要满足:

  1. 谁先完成(resolve 或 reject)就返回谁
  2. 不关心顺序
  3. 只要有一个 settle(成功或失败),就结束
  4. 支持普通值(非 Promise)
  5. 空数组 → 永远 pending(⚠️ 很多人不知道)

举个例子

👉 输出:2


分析:

race:赛跑、比赛。那么这个方法的意思就是,谁先完成,就返回谁。

那么参考Promise.all的实现方法,这个其实更简单,因为只需要返回一个settle结果,并且不关心顺序,空数组永远pending(意味着不需要考虑空数组返回什么,因为此时的promise.forEach是无法执行的,外层的promise就会一直pending),直接在then里面resolve并且catch里面reject即可。

中文

Promise.race 的核心是:

  1. 遍历所有输入
  2. 用 Promise.resolve 统一处理
  3. 谁先 resolve 或 reject,就立即结束
  4. 不需要计数或顺序控制
  5. 空数组会返回一个 pending Promise

English

The core idea of Promise.race:

  1. Iterate through all inputs
  2. Normalize using Promise.resolve
  3. Resolve or reject as soon as one settles
  4. No need for ordering or counting
  5. Empty array results in a pending Promise

我的答案:


可以优化的点:

⚠️ 点 1:空数组情况(高频考点)

正确行为:永远 pending(不会 resolve / reject)。我的答案是正确的,但是需要主动进行说明让面试官了解。

中文: 如果传入空数组,race 会返回一个永远 pending 的 Promise。因为promises.forEach不会执行。

English: If an empty array is passed, the returned Promise will remain pending forever.

 

⚠️ 点 2:可以简化写法(加分)

你现在写的是:

面试中可以写成更简洁:

为什么可以这样简写?

 

这种简化在 JavaScript 中被称为 “Point-free” 风格(或者叫函数的一等公民特性)

能够简化最底层的逻辑是:JavaScript 的函数是一等公民(First-Class Citizens),这意味着函数可以像普通变量一样被传递。

我们可以分层来看为什么它们是等价的:

1. 拆解 .then(value => resolve(value))

当我们写 value => resolve(value) 时,我们其实是创建了一个中间匿名函数(媒婆)。

2. 为什么可以直接写 .then(resolve)

因为 resolve 本身就是一个接收一个参数的函数

这就像你雇佣了一个员工(中间函数),他的工作只是把快递(value)接过来再转交给经理(resolve)。既然如此,你为什么不直接把快递交给经理呢?


3. 一个致命的“坑”:什么时候不能这样简化?

在面试中,如果你能主动指出这个简化的边界条件,会显得你的基础极其扎实。

当函数内部依赖 this 上下文(Context)时,绝对不能这样简化!

错误示例:

假设你有一个对象方法:


面试中的双语解释 (Bilingual Pitch)

"This simplification is possible because in JavaScript, functions are First-Class Citizens. They can be passed around just like values." (这种简化之所以可行,是因为在 JS 中,函数是一等公民。它们可以像值一样被传递。)

".then() expects a function definition. Both value => resolve(value) and resolve are functions that take one argument. Passing resolve directly avoids creating an unnecessary anonymous wrapper function." .then() 期望接收一个函数定义。这两者都是接收一个参数的函数。直接传递 resolve 避免了创建不必要的匿名包装函数。)

"However, we must be careful with this context. If the function we are passing relies on this, like an object method, passing it directly will break the binding, and we would need to use .bind() or keep the arrow function." (但是,我们必须小心 this 上下文。如果传递的函数依赖 this(比如对象的方法),直接传递会导致绑定丢失,此时我们需要使用 .bind() 或者保留箭头函数。)

总结

 

⚠️ 点 3:变量命名(小优化)

_ 没必要,可以去掉

 

所以最终答案可以是这样的:

 

Question 13 (用Promise封装一个超时功能)

中文解释: 给任意一个 Promise 添加超时时间,如果超过指定时间还未完成,则 reject。

English Explanation: Add a timeout to any promise. If it doesn't settle within the given time, reject with a timeout error.

面试回答模板:

“我常用 Promise.race() 来实现超时功能。一个是正常 Promise,另一个是 setTimeout 的 reject Promise,哪个先完成就用哪个。这样可以有效防止接口长时间无响应。”

Question 14 (用Promise封装一个并发限制函数)

中文解释: 实现一个函数,限制同时运行的异步任务数量(例如最多同时 3 个请求),常用于防止请求过多导致服务器压力过大,避免瞬间撑爆服务器或浏览器带宽。比如说用户上传图片、文件的时候,可以同时选中很多个文件一起上传,此时使用并发限制函数是很有效的。

English Explanation: Create a function that limits the maximum number of concurrent async tasks (e.g. max 3 requests at the same time).

 

重点:

 

思路:

我的几个问题:

为什么最后的返回结果是Promise.all(results),不应该就返回results吗?因为里面有p.finally 这样的代码啊。

我想象的过程应该是这样的:所有的tasks完成后都会返回数据,所以最后的results里面,应该都是数据而已。

错,即使tasks完成之后返回的是数据,但是task都会被包装为promise,所以返回的结果其实是promise。

并且:

p.finally 触发了,并不代表“所有任务”都完成了,它只是代表“当前某一个任务”完成了,而 for...of 循环在这个时候已经提早结束了。

让我们用时间线来拆解为什么 for 循环结束时,任务还在继续:

  1. for...of 循环只是个“发票机”

在这个函数中,for...of 循环的作用是把所有任务安排进队列,它跑得极快(几毫秒内就结束了)。

假设你有 10 个任务,限制并发为 3:

① 循环瞬间启动了任务 1、2、3,并将它们推进了 executing 池子。

② 因为池子满了(长度为 3),代码在 await Promise.race(executing) 这里暂停(卡住)了。

③ 突然,任务 1 完成了。任务 1 的 p.finally 触发,把任务 1 从池子里删掉(池子剩下 2 个)。

④ 此时 Promise.race 感知到有人完成了,解除暂停。for 循环继续往下走,立刻把任务 4 放进池子。

  1. for 循环走出去了,发生了什么?

当循环把第 10 个任务也放进池子后,for 循环就彻底结束了。 此时代码来到了最后一行:return ...

关键就在这里: 当循环结束、代码走到最后一行的时候,任务 8、9、10 往往才刚刚被放进池子里,它们还在后台努力地执行着呢! 它们的 p.finally 此时根本还没有触发

  1. 如果这时候直接 return results

正如你所说,前面完成的任务(比如任务 1、2、3)已经在历史的某个时刻触发过 p.finally 了。但最后这几个任务(8、9、10)此时还是 Promise(正在加载状态)

那最后results里面,可能是p,也可能是p完成后的结果,都放到all里面,没有问题吗?

  1. results 数组里其实“永远只有 Promise”

这是一个常见的直觉误区。你可能会觉得:任务完成了,它在 results 数组里是不是就变成具体的数据了?

答案是:不会。 results 是一个普通数组。你在第一步把它推入进去的是 p(一个 Promise 对象),那么无论过多久、无论这个任务成功还是失败,它在数组里的身份永远是一个 Promise 对象。它的外壳没有变,变的是它内部的状态(从 pending 变成了 fulfilledrejected)。

所以,当你执行 Promise.all(results) 时,它拿到的依然是一个纯 Promise 组成的数组,只是这些 Promise 的状态不同:

  1. Promise.all 是如何处理这些不同状态的?

Promise.all 的底层逻辑非常高效和聪明:

 

为什么要使用Promise.resolve().then(() => task()),这种写法。不能使用new Promise这种写法吗?

 

这两种写法在功能上其实都能达到目的,但使用 Promise.resolve().then(() => task()) 是一种更稳健、简洁的工业级写法。

以下是它们的三大核心区别:

  1. 自动处理“非 Promise”返回值

在你的 tasks 数组里,用户可能不小心传了一个普通函数(不返回 Promise 的函数)。

  1. 异常捕获更优雅

这是最关键的原因。

  1. 语义更清晰

如果你非要用 new Promise,它长这样:

为了达到同样的效果,你需要写得更复杂:

总结

使用 Promise.resolve().then(() => task()) 是一种 “懒人写法”,它利用了 Promise 的内部机制自动处理了:

  1. 同步错误捕获
  2. 返回值 Promise 化

 

为什么我很少自己创建promise呢?比如说我在nextjs项目中,写prisma数据库操作,我会直接使用async await,其余的地方也很少自己创建promise,是不是我能力不够

可以这样说,这就是工作造成的,如果工作中会用到promise,我想我会很快掌握的。

但是面试中对于promise的考察还是很有深度啊,我该怎么办?我主要是做项目,做工具、做框架都很少

掌握好这些面试题,掌握经典的promise用法即可。

promise里面如果嵌套promise的话,还是会造成回调地狱吧?

你说得非常对!如果你在 Promise 的 .then() 里面又去 new Promise() 并且在里面嵌套写 .then(),那确实会演变成“Promise 地狱”,代码看起来和以前的回调嵌套没区别。

但 Promise 设计的精髓在于“链式调用(Chaining)”,它能把嵌套结构拍平

  1. 错误示范:Promise 嵌套(地狱再现)

这种写法虽然用了 Promise,但思维还是回调函数的思维:

  1. 正确示范:链式调用(拍平逻辑)

Promise 规定:.then() 方法里的回调函数,如果返回的是一个新的 Promise,那么下一个 .then() 会等待这个 Promise 完成后再执行。

  1. 终极方案:Async/Await(看起来像同步)

为了彻底解决这种视觉上的“链条感”,ES2017 引入了 async/await。它本质上还是 Promise,但它让异步代码写起来和同步代码一模一样:

总结

我一直在写项目,promise在哪些场景里面可以应用呢?

其实我在很多地方用到了promise,比如说axios, prisma, promise.all(), fetch。使用起来我还是会的,但是我从来没有主动封装过promise相关的工具,那么可以从哪些场景提升自己应用promise的能力呢?

当你发现你正在写的逻辑里出现了 “监听某个事件(如 onSuccess, onComplete)” 或者是 “在回调函数里套回调函数” 的时候,就是你该主动封装 Promise 的信号。