自编写一套简单的Promise——myPromise

废了1-2天功夫编写了一套能实现异步Promise的构造函数,实现以下功能:

(1)通过newPromise((res,rej)=>{})构造一个Promise功能的方法

(2)通过then获取onFulfilled或者onRejected状态返回的值

(3)通过catch捕获之前rejected的错误

/*promise状态,PENDING阻塞、FULFILLED完成、REJECTED失败*/
const PENDING = 0,
    FULFILLED = 1,
    REJECTED = 2;

/*then中需要返回一个新的promise,promise初始化用的resolver*/
function noop() {
};

/*resolver必须为一个方法,不是给出typeError提示*/
function needsResolver() {
    throw new TypeError('You must pass a resolver function as the first argument to the promise constructor')
}

/*Promise构造函数生成,不是给出typeError提示*/
function needsNew() {
    throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.")
}


class newPromise {
    constructor(resolver) {
        /*当前Promise状态*/
        this.PromiseStatus = PENDING
        /*final执行时需要的标记,防止乱序执行*/
        this._deferredState = 0 //1在进行final  否则不在
        /*存放的后续then执行的({onFulfilled,onRejected})方法*/
        this._deferreds = []
        /*保存当前值,可以是resolve或者reject返回的值*/
        this.PromiseValue = null
        /*resolver是否是方法,不是提示报错信息*/
        typeof resolver !== 'function' && needsResolver();
        this instanceof newPromise ? init_(this, resolver) : needsNew();
    }
}

newPromise.prototype.then = then_
newPromise.prototype.catch = catch_

function init_(promise, resolver) {
    try {
        resolver((val) => {
            resolve_(promise, val)
        }, (err) => {
            reject_(promise, err)
        })
    } catch (e) {
        catch_(e)
    }
}

/*与then相似,只是没有onFulfilled参数*/
function catch_(onRejected) {
    var promise = new newPromise(noop);
    let handler = new Handler(this, null, onRejected, promise)
    pushTo_(this, handler)
    return promise;
}

/*reject,resolve之后会调用*/
function final_(promise) {
    if (promise._deferreds.length > 0) {//将结果返回
        if (promise._deferredState === 1) return
        promise._deferredState = 1
        let defer = promise._deferreds[0]
        handle_(promise, defer);
    }
}

function pushTo_(promise, deferred) {
    promise._deferreds.push(deferred)
}

function handle_(self, defer) {//{defer 是一个对象,有三个参数:onFulfilled,onRejected,promise
    var cb = self.PromiseStatus === FULFILLED ? defer.onFulfilled : defer.onRejected;
    if (cb === null) {
        /*状态不变,再次调用then才将PromiseValue输出*/
        self._deferreds.pop()
        if (self.PromiseStatus === FULFILLED) {
            resolve_(self, self.PromiseValue)
        } else {
            reject_(self, self.PromiseValue)
        }
        self._deferredState = 0
    }
    else if (self.PromiseStatus === PENDING) {
        // if (self._deferredState === 0) {
        //     self._deferredState = 1;
        // }
    }
    else {
        self._deferreds.pop()
        self._deferredState = 0
        let promise = self.promise
        let callback = cb(self.PromiseValue)
        if (callback) {
            callback.then(res => {
                // console.log('---', callback)
                // if (callback.PromiseStatus === REJECTED)
                //     reject_(promise, callback.PromiseValue)
                // else
                /*将callback返回值,在之前then生成的promise上发出,则promise.then可以捕获到,这样then就可以变成链式的了*/
                resolve_(promise, callback.PromiseValue)
            }, rej => {
                reject_(promise, callback.PromiseValue)
            })
        }
    }
}


//返回一个新的promise
function then_(onFulfilled, onRejected) {
    var promise = new newPromise(noop);
    let handler = new Handler(this, onFulfilled, onRejected, promise)
    pushTo_(this, handler)
    return promise;
}


function resolve_(promise, val) {
    promise.PromiseStatus = FULFILLED
    promise.PromiseValue = val
    final_(promise)
}

function reject_(promise, err) {
    promise.PromiseStatus = REJECTED
    promise.PromiseValue = err
    final_(promise)
}


function Handler(promise, onFulfilled, onRejected, promise_) {
    promise.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
    promise.onRejected = typeof onRejected === 'function' ? onRejected : null;
    promise.promise = promise_;
    return promise
}

复制代码

测试代码:


let newp = new newPromise((resolve, reject) => {
    setTimeout(() => {
        reject('1')
    })
}).then(resolve => {
    console.log('resolve', resolve)
}, reject => {
    console.log('reject:', reject)
    return new newPromise((resolve) => {
        setTimeout(() => {
            resolve('ok')
        }, 100)
    })
}).then(res => {
    console.log('---res---', res)
    return new newPromise((resolve, reject) => {
        setTimeout(() => {
            reject('ok')
        }, 100)
    })
}).then(res => {
    console.log('---res2---', res)
}, rej => {
    console.log('---rej2---', rej)
    return new newPromise((resolve, reject) => {
        setTimeout(() => {
            reject('err')
        }, 100)
    })
}).catch(err => {
    console.log(err)
})
复制代码

测试结果:

转载于:https://juejin.im/post/5d53e9b75188255db76bf89a

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值