MST

星途 面试题库

面试题:Node.js 中 Promise 的底层实现及优化策略

假设你需要在 Node.js 中手动实现一个简易的 Promise 类,要求支持基本的 resolve、reject 状态变化,链式调用 then 方法,以及错误处理机制。请描述实现思路,并指出在实际生产环境中,针对 Promise 的性能优化,你会考虑哪些方面及采取何种策略。
34.5万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 状态管理:定义三个状态常量 PENDINGFULFILLEDREJECTED,在 Promise 类内部使用一个变量 status 来记录当前状态,初始为 PENDING。同时使用 valuereason 变量分别存储成功和失败的值。
  2. 构造函数:接受一个执行器函数 executor,在构造函数内部立即执行该执行器,并传入 resolvereject 函数。resolvereject 函数用于改变 Promise 的状态。
  3. resolve 函数:如果当前状态是 PENDING,则将状态改为 FULFILLED,并保存传入的值到 value 中。同时触发所有已注册的成功回调。
  4. reject 函数:如果当前状态是 PENDING,则将状态改为 REJECTED,并保存传入的原因到 reason 中。同时触发所有已注册的失败回调。
  5. then 方法:返回一个新的 Promise。它接受两个回调函数 onFulfilledonRejected,这两个函数分别在 Promise 成功或失败时被调用。如果 Promise 已经处于 FULFILLED 状态,直接调用 onFulfilled;如果处于 REJECTED 状态,直接调用 onRejected;如果处于 PENDING 状态,则将这两个回调函数注册到内部的回调队列中,等待状态改变时调用。
  6. 错误处理:在 then 方法中,如果 onFulfilledonRejected 抛出错误,新返回的 Promise 应该进入 REJECTED 状态,并将该错误作为原因。同时,在执行器函数 executor 中,如果发生错误,应该调用 reject 函数将 Promise 变为 REJECTED 状态。

性能优化方面及策略

  1. 减少不必要的微任务:Promise 的 then 方法会创建微任务,过多的微任务可能导致性能问题。尽量合并多个连续的 then 调用,减少微任务的数量。例如,避免无意义的中间 then 调用,直接链式调用有实际操作的 then
  2. 缓存结果:对于一些计算开销较大且结果不变的 Promise,可以缓存其结果。如果相同的 Promise 再次被调用,可以直接返回缓存的结果,而不需要重新执行异步操作。
  3. 避免过度嵌套:过度嵌套的 Promise 链式调用会增加代码复杂度,同时也可能影响性能。可以使用 Promise.allPromise.race 等方法来并行处理多个 Promise,提高执行效率。
  4. 错误处理优化:在 Promise 链式调用中,尽早捕获错误,避免错误在链式调用中传递到不必要的层级。这样可以减少不必要的错误处理代码执行,提高性能。同时,合理使用 catch 方法,确保错误处理逻辑简洁高效。