promise 是什么, 底层如何实现

Promise是一个对象,保存着未来将要结束的事件,她有两个特征:

1、对象的状态不受外部影响,Promise对象代表一个异步操作,有三种状态,pending进行中,fulfilled已成功,rejected已失败,只有异步操作的结果,才可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,这也就是promise名字的由来

2、一旦状态改变,就不会再变,promise对象状态改变只有两种可能,从pending改到fulfilled或者从pending改到rejected,只要这两种情况发生,状态就凝固了,不会再改变,这个时候就称为定型resolved,

原理

一句话总结promise原理:resolve, reject两个函数控制promise内部状态,promise.then()根据状态执行不同的逻辑,实现异步。

Promise其实内部也有一个defers队列存放事件,.then的事件就在里面,聪明的你就想到了,程序开始执行的时候,.then就已经放入下一个事件,然后后面当异步操作完成时,resolve触发事件队列中的事件,便完成了一个.then操作,

其实到这里我们就可以很快地想出一种解决方案,每次异步操作完成通过resolve触发事件并将事件从事件队列中移除,通过事件队列中的事件的resolve使事件的触发持续下去

每个Promise实例包含状态state、事件队列defers、value、resolve、reject

还有一个handle函数,当状态为pending时是将Defered{}(包含onFulfilled、onRejected、resolve、reject)放入队列的操作,当状态为fulfilled或rejected会执行相应事件的函数onFulfilled/onRejected并且resolve返回的东西

然后为了实现串行Promise,.then其实又产生了一个新的Promise实例作为中间Promise, 它将then里的函数再与自己的实例中的resolve,reject共同组成一个Defered{}(包含onFulfilled、onRejected、resolve、reject),注意这里非常关键,这将是串行Promise桥梁的关键之处(通过闭包实现的),用handle函数把这个对象放入前一个Promise实例的事件队列里。

简单代码实现 Promise

class Promise {
    constructor (process) {
        this.msg = "";
        this.status = "pending";
        process(this.resolve.bind(this), this.reject.bind(this));
        return this;
    }
    
    resolve (val) {
        this.msg = val;
        this.status = "fulfilled";
    }
    reject (val) {
        this.msg = val;
        this.status = "rejected";
    }
    
    then (fulfilled, rejected) {
        if (this.status === "fulfilled") {
            fulfilled(this.msg);
        }
        if (this.status === "rejected") {
            rejected(this.msg);
        }
    }
}

来源整理自:vue3js.cn 面试官系列