面试题答案
一键面试实现思路
- 状态管理:定义三个状态常量
PENDING
、FULFILLED
、REJECTED
,在Promise
类内部使用一个变量status
来记录当前状态,初始为PENDING
。同时使用value
和reason
变量分别存储成功和失败的值。 - 构造函数:接受一个执行器函数
executor
,在构造函数内部立即执行该执行器,并传入resolve
和reject
函数。resolve
和reject
函数用于改变Promise
的状态。 - resolve 函数:如果当前状态是
PENDING
,则将状态改为FULFILLED
,并保存传入的值到value
中。同时触发所有已注册的成功回调。 - reject 函数:如果当前状态是
PENDING
,则将状态改为REJECTED
,并保存传入的原因到reason
中。同时触发所有已注册的失败回调。 - then 方法:返回一个新的
Promise
。它接受两个回调函数onFulfilled
和onRejected
,这两个函数分别在Promise
成功或失败时被调用。如果Promise
已经处于FULFILLED
状态,直接调用onFulfilled
;如果处于REJECTED
状态,直接调用onRejected
;如果处于PENDING
状态,则将这两个回调函数注册到内部的回调队列中,等待状态改变时调用。 - 错误处理:在
then
方法中,如果onFulfilled
或onRejected
抛出错误,新返回的Promise
应该进入REJECTED
状态,并将该错误作为原因。同时,在执行器函数executor
中,如果发生错误,应该调用reject
函数将Promise
变为REJECTED
状态。
性能优化方面及策略
- 减少不必要的微任务:Promise 的
then
方法会创建微任务,过多的微任务可能导致性能问题。尽量合并多个连续的then
调用,减少微任务的数量。例如,避免无意义的中间then
调用,直接链式调用有实际操作的then
。 - 缓存结果:对于一些计算开销较大且结果不变的
Promise
,可以缓存其结果。如果相同的Promise
再次被调用,可以直接返回缓存的结果,而不需要重新执行异步操作。 - 避免过度嵌套:过度嵌套的
Promise
链式调用会增加代码复杂度,同时也可能影响性能。可以使用Promise.all
或Promise.race
等方法来并行处理多个Promise
,提高执行效率。 - 错误处理优化:在
Promise
链式调用中,尽早捕获错误,避免错误在链式调用中传递到不必要的层级。这样可以减少不必要的错误处理代码执行,提高性能。同时,合理使用catch
方法,确保错误处理逻辑简洁高效。