高级开发者必须掌握的手写Promise(一)

1、概述

了解了Promise A+之后,我们就可以根据规范实现自己的Promise了,如果对规范记得不是很清楚,建议边看规范边写自己的Promise库~

回忆下规范,一个Promise应该有哪些基本的功能?

  • 测试手机是否被监控有三个状态
  • 状态的扭转
  • 执行(resolve)成功的value
  • 执行(re测试ject)失败的reason
  • 注册了两个回调函数resolve和reject,用于接收 promise 的终值或本 promise 不能执行的原因,分别将状态从pending扭转为resolved和reject数组的定义ed,并设置value和reas测试你的自卑程度on
  • 具有then方法
  • then方法也要返回一个Promise实例
promise.then(onFulfilled, onRejected)

以上大概可以猜到一个Promi数组的定义se可以用对象来实现~

2、实现一个简单的Promise

先看下Promise提供的功能,我们照着实现相同的功能~

let promise1 = new Promise((resolve, reject) => {
    resolve('resolve: lls value is OK~');
    //reject('reject: lls reason is Fail~');
    //throw new Error('Sorry lls is Error~')
});
promise1.then(value => {
    console.log(`onFulfilled:`, value);
}, (reason) => {
    console.log(`onRejected:`, reason);
});
//分别打印出
//onFulfilled: resolve: lls value is OK~
//onRejected: reject: lls reason is Fail~
//onRejected: Error: Sorry lls is Error~

具体实现如下

//状态枚举
const STATUS = {
    PENDING: 'PENDING',
    FULFILLED: 'FULFILLED',
    REJECTED: 'REJECTED'
}
class llsPromise {
    constructor(executor) {
        //最初始状态
        this.state = STATUS.PENDING;
        this.value = undefined;  //值或者终值
        this.reason = undefined; //拒因或者失败原因
        const resolve = function (value) { // resolve函数,功能是扭转状态为fulFilled&设置终值
            if(this.state === STATUS.PENDING) {
                this.state = STATUS.FULFILLED;
                this.value = value;
            }
        }.bind(this)
        const reject = function (reason) { // reject函数,功能是扭转状态为rejected&设置拒因
            if(this.state === STATUS.PENDING) {
                this.state = STATUS.REJECTED;
                this.reason = reason;
            }
        }.bind(this)
        try{ //捕获异常,并执行reject,保存错误的时候扭转状态为rejected&设置拒因
            executor(resolve, reject);
        }catch(e){
            reject(e);
        }
    }
    //接受两个参数 onFulfilled和onRejected
    then(onFulfilled, onRejected) {
        if(this.state === STATUS.FULFILLED && onFulfilled && isFunction(onFulfilled)) {
            //接收 promise 的终值
            onFulfilled(this.value);
        }
        if(this.state === STATUS.REJECTED && onRejected && isFunction(onRejected)) {
            //接收 promise 的拒因
            onRejected(this.reason);
        }
    }
}
function isFunction(value) {
    return typeof value === 'function' && typeof value.nodeType !== 'number';
}

测试一下,测试你的自卑程度符合预期,一个最简单的Promise就实现了

let promise1 = new llsPromise((resolve, reject) => {
    resolve('llsPromise resolve: lls value is OK~');
    //reject('llsPromise reject: lls reason is Fail~');
    //throw new Error('Sorry lls is Error~')
});
promise1.then(value => {
    console.log(`onFulfilled:`, value);
}, (reason) => {
    console.log(`onRejected:`, reason);
});
//分别打印出
//onFulfilled:llsPromise  resolve: lls value is OK~
//onRejected:llsPromise  reject: lls reason is Fail~
//onRejected:llsPromise  Error: Sorry lls is Error~

3、上面的Promise能够处理异步数组的定义吗?

试一下~

let promise1 = new llsPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('llsPromise resolve: lls value is OK~');
        //reject('llsPromise reject: lls reason is Fail~');
        //throw new Error('Sorry lls is Error~')  
    }, 2000);
});
promise1.then(value => {
    console.log(`onFulfilled:`, value);
}, (reason) => {
    console.log(`onRejected:`, reason);
});
// 打印不出任何东西

测试你的自卑程度然是不满足需求的,那到底是为啥?

原因由于resolve数组词或者reject是异步执行的,当执行到then的时候,状态还未改变,因此:
onFulfilled(this数组去重.value) 和 onRejected(this.reason)都不会执行

then(onFulfilled, onRejected) {
    if(this.state === STATUS.FULFILLED && onFulfilled && isFunction(onFulfilled)) {
        //接收 promise 的终值
        onFulfilled(this.value);
    }
    if(this.state === STATUS.REJECTED && onRejected && isFunction(onRejected)) {
        //接收 promise 的拒因
        onRejected(this.reason);
    }
}

该怎么解决呢?

思考一下,最好是能够知道什么时候状态改变,然后测试抑郁程度的问卷执行对应的onFul测试用例filled或者测试你适合学心理学吗onRejected回调,而状态的改变在resolve测试抑郁程度的问卷和reject方法中,因此可以在这两个方法中调用对应的onFulfilled或者onRejected回调;但是需要把回调存储起来,代码改变数组词如下:

1、新增onFulfilledCallbacks和onRejectedCa测试你适合学心理学吗ll测试工程师backs用于存储onFulfilled或者onReje测试cted回调

//存储异步回调,为啥用数组,是因为promise实例可以多次调then, 
this.onFulfilledCallbacks = []; 
this.onRejectedCallbacks = [];

2、将onFulfilled回调存测试你适合学心理学吗储在onFulfilledCallbacks中,将onFulfilled数组词回调存测试仪储在onFulfilledCallbacks中

if(onFulfilled && isFunction(onFulfilled)) {
    //将onFulfilled回调存储在onFulfilledCallbacks中
    this.onFulfilledCallbacks.push(() => {
        onFulfilled(this.value);
    });
}
if(onRejected && isFunction(onRejected)) {
    //将onFulfilled回调存储在onFulfilledCallbacks中
    this.onRejectedCallbacks.push(() => {
        onRejected(this.reason);
    });
}

3、执行o测试工程师nFulfilledCallbacks和onRe数组去重方法jectedCallbacks回调函数

const resolve = function (value) {
    if(this.state === STATUS.PENDING) {
        this.state = STATUS.FULFILLED;
        this.value = value;
        //执行onFulfilledCallbacks
        this.onFulfilledCallbacks.forEach(cb => {
            cb();
        });
    }
}.bind(this)
const reject = function (reason) {
    if(this.state === STATUS.PENDING) {
        this.state = STATUS.REJECTED;
        this.reason = reason;
        //执行onFulfilledCallbacks
        this.onRejectedCallbacks.forEach(cb => {
            cb();
        });
    }
}.bind(this)

完整代码如下~

//状态枚举
const STATUS = {
    PENDING: 'PENDING',
    FULFILLED: 'FULFILLED',
    REJECTED: 'REJECTED'
}
class llsPromise {
    constructor(executor) {
        //最初始状态
        this.state = STATUS.PENDING;
        this.value = undefined;  //值或者终值
        this.reason = undefined; //拒因或者失败原因
        //存储异步回调,为啥用数组,是因为promise实例可以多次调then,
        this.onFulfilledCallbacks = [];
        this.onRejectedCallbacks = []; 
        const resolve = function (value) { // resolve函数,功能是扭转状态为fulFilled&设置终值
            if(this.state === STATUS.PENDING) {
                this.state = STATUS.FULFILLED;
                this.value = value;
                this.onFulfilledCallbacks.forEach(cb => {
                    cb();
                });
            }
        }.bind(this)
        const reject = function (reason) { // reject函数,功能是扭转状态为rejected&设置拒因
            if(this.state === STATUS.PENDING) {
                this.state = STATUS.REJECTED;
                this.reason = reason;
                this.onRejectedCallbacks.forEach(cb => {
                    cb();
                });
            }
        }.bind(this)
        try{ //捕获异常,并执行reject,保存错误的时候扭转状态为rejected&设置拒因
            executor(resolve, reject);
        }catch(e){
            reject(e);
        }
    }
    //接受两个参数 onFulfilled和onRejected
    then(onFulfilled, onRejected) {
        if(onFulfilled && isFunction(onFulfilled)) {
            //将onFulfilled回调存储在onFulfilledCallbacks中
            this.onFulfilledCallbacks.push(() => {
                onFulfilled(this.value);
            });
        }
        if(onRejected && isFunction(onRejected)) {
            //将onFulfilled回调存储在onFulfilledCallbacks中
            this.onRejectedCallbacks.push(() => {
                onRejected(this.reason);
            });
        }
    }
}
function isFunction(value) {
    return typeof value === 'function' && typeof value.nodeType !== 'number';
}

再执行下异步的代码,就会符合预期结果

4、总结

这样就初步实现了测试抑郁程度的问卷Promise的基本的数组长度功能,关于then方法必须返回一个promise对象的实现将在下一篇实现~

发表评论

提供最优质的资源集合

立即查看 了解详情