6.then链式调用 传入promise时

32 阅读1分钟
// then链式调用 成功回调的返回值为promise对象时
const PENDING = 'pending'
const FUFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
    constructor (executor) {
        executor(this.resolve, this.reject)
    }
    status = PENDING
    value = undefined
    reason = undefined
    successCallback = []
    failCallback = []

    resolve = value => {
        if (this.status !== PENDING) return
        this.status = FUFILLED
        this.value = value
        while(this.successCallback.length) this.successCallback.shift()(this.value)
    }
    reject = reason => {
        if (this.status !== PENDING) return
        this.status = REJECTED
        this.reason = reason
        while(this.failCallback.length) this.failCallback.shift()(this.reason)
    }
    then(successCallback, failCallback) {
        const promise2 = new MyPromise((resolve, reject) => {
            if (this.status === FUFILLED) {
                const successValue = successCallback(this.value)
                // 判断 successValue 是普通值还是Promise对象
                // 如果是普通值 直接调用resolve
                // 如果是promise,则先查看promise返回的结果
                // 再根据promise返回的结果 决定调用 resolve 或者 reject
                resolvePromise(successValue, resolve, reject)
            } else if (this.status === REJECTED) {
                failCallback(this.reason)
            } else {
                this.successCallback.push(successCallback)
                this.failCallback.push(failCallback)
            }
        })
        return promise2
    }
}
function resolvePromise(successValue, resolve, reject) {
    // 判断返回的值是否是promise对象
    if (successValue instanceof MyPromise) {
        successValue.then(value => resolve(value), reason => reject(reason))
    } else {
        resolve(successValue)
    }
}

// 验证
const mypromise =  new MyPromise((resolve, reject) => {
    // setTimeout(() => {
    //     resolve('successValue')
    // }, 2000)
    resolve('successValue')
    // reject('failReason')
})

function other () {
    return new MyPromise((resolve, reject) => {
        resolve('other')
    })
}

mypromise.then(
    values => {
        console.log(values)
        return 100
    },
    reason => {
        console.log(reason)
    }
)
.then(
    values => {
        console.log(values)
        return other()
    }, 
    reason => {
        console.log(reason)
    }
)
.then(
    values => {
        console.log(values)
    }, 
    reason => {
        console.log(reason)
    }
)