Promises的实现原理是什么?

一语呢喃醉 2023-10-02 14:02:00 浏览数 (1160)
反馈

Promises的实现原理是什么?


Promises的实现原理可以通过以下4步概括:

  1. Promise有3种状态:pending、fulfilled和rejected。初始状态为pending。
  2. Promise实例包含一个then方法,then方法接受两个参数:onFulfilled和onRejected,分别为promise成功或失败的回调。
  3. Promise有一个内部属性[[PromiseState]],初始值为pending。内部又有一个属性[[PromiseResult]],初始值为undefined。
  4. Promise的状态只能从pending到fulfilled或rejected,状态一旦改变就不能再变。 fulfilled和rejected状态都会触发then里的回调。

当我们new一个Promise时,会传入一个执行器executor,执行器会立即执行。在执行器中我们可以处理异步任务,比如发送ajax请求,一旦异步任务执行结束,就可以决定是resolve(成功)还是reject(失败)这个promise。

如果执行resolve,那么将[[PromiseState]]设为fulfilled,[[PromiseResult]]设为传入的值。执行onFulfilled回调。

如果执行reject,那么将[[PromiseState]]设为rejected,[[PromiseResult]]设为传入的reason。执行onRejected回调。

这样通过状态和结果的改变,来触发then里不同的回调,从而实现异步流程的控制。

Promise就是通过状态改变来触发回调的,这也是它实现异步编程的基石。

如果在Promise的执行器函数(executor)中不调用resolve或reject, 会怎么样?

如果在Promise的执行器函数(executor)中不调用resolve或reject,通常会导致两个结果:

  • Promise对象的状态永远保持pending

Promise对象代表一个异步操作,它的最终状态应该在某个时刻确定下来(fulfilled或rejected)。如果executor函数中不调用resolve或reject,Promise的状态就无法得以确定,会永远处于pending状态。

  • then方法指定的回调函数不会被调用

then方法注册的回调函只有在Promise状态确定后才会被调用,如果状态一直是pending,那么then方法的回调函数就永远不会被执行。

所以,如果在executor函数中不调用resolve或reject,就是一个错误的实现,违反了Promise/A+规范。

正确的做法是,在executor函数中,无论异步任务是否成功,都需要在最后调用resolve或者reject,将Promise的状态确定下来,以便触发then方法注册的回调。通常like这样:

new Promise((resolve, reject) => { // ...做一些异步操作 if(成功) { resolve(value); } else { reject(error); } })

所以,不调用resolve/reject,将导致Promise永远pending,然后注册的回调函数也就不会执行。这违反Promise的设计初衷,应该避免这样使用。


0 人点赞