手写Promise (一)

110 阅读3分钟

Promise的使用方式

let promise = new MyPromise((resolve, reject) => {
    resolve('成功');
    // reject('失败');
})

1、Promise 就是一个类 在执行这个类的时候,需要传递一个执行器进去 执行器会立即执行

2、resolve、reject用于处理成功、失败的回调;

于是我们的promise可以这样来实现:

class MyPromise {
    constructor (executor) {
        executor(this.resolve, this.reject);
    }
    // 定义箭头函数,由于使用是直接调用的,所以使用箭头函数,
    // 让this指向promise对象
    resolve = (value) => {
        // 保存成功之后的值
        this.value = value;
    }
    reject = (reason) => {
        // 保存失败原因
        this.reason = reason;
    }
}

此时保证了MyPromise类中提供了回调结果value、回调原因reason 的存储,以及resolve、reject方法

3、Promise是有三个状态的 pendding \ fulfilled \ rejected,之所以有这三个状态,是因为Promise作为一个解决异步函数的功能,需要在状态从pendding进入fulfilled或者rejected的时候,触发回调。来完成最终的回调;

所以,我们把pendding是初始状态,当pendding进入fulfilled或者rejected的时候,证明Promise已经完成异步回调,可以进行下一步处理。

由于回调一次只能有一个,那么fulfilled跟rejected是不可互转的,而结果能有一次,那么pendding与fulfilled、rejected是不可逆的。

于是我们的promise可以进一步来实现:

const PENDDING = 'pendding'; // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
    constructor (executor) {
        executor(this.resolve, this.reject);
    }
    // 默认等待
    status = PENDDING;
    // 成功之后的值
    value = undefined;
    // 失败原因
    reason = undefined;
    // 定义箭头函数,由于使用是直接调用的,所以使用箭头函数,
    // 让this指向promise对象
    resolve = (value) => {
        // 不是等待,拒绝执行
        // 将状态更改为成功
        if (this.status !== PENDDING) {
            return;
        }
        this.status = FULFILLED;
        // 保存成功之后的值
        this.value = value;
    }
    reject = (reason) => {
        // 不是等待,拒绝执行
        if (this.status !== PENDDING) {
            return;
        }
        // 将状态更改为失败
        this.status = REJECTED;
        // 保存失败原因
        this.reason = reason;
    }
}

通过resolve、reject回调,来修改一个promise的状态,并且不允许状态之间互相二次切换。

4、Promise提供了一个then方法,来完成状态改变之后的事件结果获取。

then = (successCallBack, failCallBack) => {
        // 判断状态
        if (this.status === FULFILLED) {
            successCallBack(this.value);
        } else if (this.status === REJECTED) {
            failCallBack(this.reason);
        }
    }

根据3的结论,根据promise的最终状态,触发成功或者失败回调。

阶段一: 此时,我们就完成了基本的代码骨架,可以实现Promise的状态改变、then调用;

/** 
 * 1、Promise 就是一个类 在执行这个类的时候,需要传递一个执行器进去 执行器会立即执行
 * 2、Promise 中有三种状态 分别为 成功 fulfilled 失败 rejected 等待 pendding
 *  pendding -> fulfilled
 *  pendding -> rejected
 * 3、resolve和reject函数是用来更改状态的
 *  resolve:fulfilled
 *  reject:rejected
 * 4、then方法内部,先判断状态,根据状态,调用resolve或者reject
 *  then是被定义在原型对象中的
 * 5、then成功回调有一个参数,表示成功之后的值;有一个值,表示失败之后的原因
 *  这些值是从resolve、reject回传的
*/
const PENDDING = 'pendding'; // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
    constructor (executor) {
        executor(this.resolve, this.reject);
    }
    // 默认等待
    status = PENDDING;
    // 成功之后的值
    value = undefined;
    // 失败原因
    reason = undefined;
    // 定义箭头函数,由于使用是直接调用的,
    所以使用箭头函数,让this指向promise对象
    resolve = (value) => {
        // 不是等待,拒绝执行
        // 将状态更改为成功
        if (this.status !== PENDDING) {
            return;
        }
        this.status = FULFILLED;
        // 保存成功之后的值
        this.value = value;
    }
    reject = (reason) => {
        // 不是等待,拒绝执行
        if (this.status !== PENDDING) {
            return;
        }
        // 将状态更改为失败
        this.status = REJECTED;
        // 保存失败原因
        this.reason = reason;
    }
    then = (successCallBack, failCallBack) => {
        // 判断状态
        if (this.status === FULFILLED) {
            successCallBack(this.value);
        } else if (this.status === REJECTED) {
            failCallBack(this.reason);
        }
    }
}

let promise = new MyPromise((resolve, reject) => {
    resolve('成功');
    // reject('失败');
})

promise.then((value) => {
    console.log(value);
}, (err) => {
    console.log(err);
});

文章内容输出来源:拉勾教育Java高薪训练营;