首先我们要搞清楚Promise怎么用的,需要做那些事
`

let myPromise = () => {
    return new Promise ((resove, reject) => {
        myajax({
            url: 'xxx',
            success: function (res) {
                resolve(res)
            },
            error: function (err) {
                reject(err)
            }
        })
    })
}
myPromise.then().then()

`
或者
`

    new Promise ((resove, reject) => {
        myajax({
            url: 'xxx',
            success: function (res) {
                resolve(res)
            },
            error: function (err) {
                reject(err)
            }
        }) 异步操作
    })
    .then()
    .then()

`
其实,promise主要是异步操作完成后,再执行指定操作。
new Promise执行指定异步操作
then中获得异步操作结果,并执行指定回调

那么,实例化Promise时需要执行该异步操作,比如发送一个ajax请求
`

myajax({
    url: 'xxx',
    success: function (res) {
        resolve(res)
    },
    error: function (err) {
        reject(err)
    }
})

`
那么,第一步可以写
`

class Promise {
    constructor(fn) {
        fn(_resolve.bind(this), _reject.bind(this))
    }
    _resolve (value) {
        
    }
    _reject (value) {
        
    }
}

`
其中参数fn一个异步操作,参数_resove是操作成功时用于返回值的回调,reject是操作失败时的回调
_resove执行什么呢? resolve(res)可知,它是有一个参数的,异步操作的结果。在拿到这个异步操作的结果后,需要执行指定回调

`

class Promise {
    value = null
    cbs = []
    constructor(fn) {
        fn(_resolve.bind(this), _reject.bind(this))
    }
    _resolve (value) {
        this.value = value
        this.cbs.forEach(cb => cb)
    }
    _reject (value) {
        
    }
}

`
cbs是异步操作成功后需要展开的下一步操作,那么cbs从哪里来的?
其实是使用者在then中注册的
那么有
`

class Promise {
    value = null
    cbs = []
    constructor(fn) {
        fn(_resolve.bind(this), _reject.bind(this))
    }
    then (onFulFilled) {
        this.cbs.push(onFulFilled)
    }
    _resolve (value) {
        this.value = value
        this.cbs.forEach(cb => cb)
    }
    _reject (value) {
        
    }
}

`
仔细考虑,会有问题,从文章一开始的promise使用例子来看,如果传入构造函数的不是异步操作,而是同步操作,那么在注册then之前就先执行了resolve,cbs就是空数组了
所以,我们需要确保,不管then在resolve前注册还是在resolve后注册,都可以被执行到。所以需要状态值pending、fulfilled来帮助实现
`

class Promise {
    value = null
    cbs = []
    state='pending'
    constructor(fn) {
        fn(_resolve.bind(this), _reject.bind(this))
    }
    then (onFulFilled) {
        if (this.state === 'pending') {
            this.cbs.push(onFulFilled)
        } else if (this.state === 'fulfilled'){
            onFulFilled(this.value)
        }
    }
    _resolve (value) {
        this.state = 'fulfilled'
        this.value = value
        this.cbs.forEach(cb => cb)
    }
    _reject (value) {
        
    }
}

`
到这里,大体轮廓完成了。但是promise使用特点是链式调用then, 也就是每一个then执行完成后都会返回一个promise实例给下一个then。这个promis实例可以是当前实例吗?考虑到当前then执行结果要返回给下一个then作为参数,这个写法不行。所以需要新建一个实例,传递给下一个then
`

class Promise {
    value = null
    cbs = []
    state='pending'
    constructor(fn) {
        fn(_resolve.bind(this), _reject.bind(this))
    }
    then (onFulFilled) {
        return new Promise((resolve, reject) => {
            if (this.state === 'pending') {
                this.cbs.push(onFulFilled)
            } else if (this.state === 'fulfilled'){
                let res = onFulFilled(this.value)
                resolve(res)
            }
        })
    }
    _resolve (value) {
        this.state = 'fulfilled'
        this.value = value
        this.cbs.forEach(cb => cb)
    }
    _reject (value) {
        
    }
}

`
填充好reject
`

class Promise {
    value = null
    cbs = []
    state='pending'
    constructor(fn) {
        fn(_resolve.bind(this), _reject.bind(this))
    }
    then (onFulFilled, onRejected) {
        return new Promise((resolve, reject) => {
            if (this.state === 'pending') {
                this.cbs.push(onFulFilled)
            } else if (this.state === 'fulfilled'){
                let ret = onFulFilled(this.value)
                resolve(ret)
            } else if (this.state === 'rejected') {
                let ret = onRejected(this.value)
                reject(ret)
            }
        })
    }
    _resolve (value) {
        this.state = 'fulfilled'
        this.value = value
        this.cbs.forEach(cb => {
            let ret = cb(value)
            cb.resolve(ret)
        })
    }
    _reject (err) {
        this.state = 'fulfilled'
        this.value = err
        this.cbs.forEach(cb => {
            let ret = cb(value)
            cb.reject(ret)
        })
    }
}

`

下面考虑异常处理问题
对于异常情形,走reject同样路径
因此有
`

class Promise {
    value = null
    cbs = []
    state='pending'
    constructor(fn) {
        fn(_resolve.bind(this), _reject.bind(this))
    }
    then (onFulFilled, onRejected) {
        return new Promise((resolve, reject) => {
            if (this.state === 'pending') {
                this.cbs.push(onFulFilled)
            } else if (this.state === 'fulfilled'){
                let ret = onFulFilled(this.value)
                resolve(ret)
            } else if (this.state === 'rejected') {
                let ret = onRejected(this.value)
                reject(ret)
            }
        })
    }
    _resolve (value) {
        this.state = 'fulfilled'
        this.value = value
        this.cbs.forEach(cb => {
            let ret = cb(value)
            cb.resolve(ret)
        })
    }
    _reject (err) {
        this.state = 'fulfilled'
        this.value = err
        this.cbs.forEach(cb => {
            let ret = cb(value)
            cb.reject(ret)
        })
    }
    catch(onError) {
        this.then(null, onError)
    }
}

`
下一步考虑finally
无论resolve还是reject都要执行finally,那么差不多是 then(func, func),但是我们的then()是返回本次then执行结束生成的一个promise实例,后面的then和前面的then执行结果有依赖关系,而finally则不需要,所以可以
`

class Promise {
    value = null
    cbs = []
    state='pending'
    constructor(fn) {
        fn(_resolve.bind(this), _reject.bind(this))
    }
    then (onFulFilled, onRejected) {
        return new Promise((resolve, reject) => {
            if (this.state === 'pending') {
                this.cbs.push(onFulFilled)
            } else if (this.state === 'fulfilled'){
                let ret = onFulFilled(this.value)
                resolve(ret)
            } else if (this.state === 'rejected') {
                let ret = onRejected(this.value)
                reject(ret)
            }
        })
    }
    _resolve (value) {
        this.state = 'fulfilled'
        this.value = value
        this.cbs.forEach(cb => {
            let ret = cb(value)
            cb.resolve(ret)
        })
    }
    _reject (err) {
        this.state = 'fulfilled'
        this.value = err
        this.cbs.forEach(cb => {
            let ret = cb(value)
            cb.reject(ret)
        })
    }
    catch(onError) {
        this.then(null, onError)
    }
    finally(onFinal) {
        return 
    }
}

`


清晖
95 声望2 粉丝

认识生活的真相后仍然热爱生活,是真正的英雄