废话不多说,直接上代码:


console.log('start')

// let a = new Promise((resolve, reject) => {
//     console.log('exec promise a')
//     resolve()
//     // setTimeout(() => {
//     //     resolve()
//     // })
//     console.log('after resolve a')
// })
// a.then((result) => {
//     console.log('promise then1 a')
// }).then((result) => {
//     console.log('promise then2 a')
// })

class Promise2 {
    static PENDING = 'PENDING'
    static FULLFILLED = 'FULLFILLED'
    static REJECTED = 'REJECTED'

    constructor(func) {
        this.status = Promise2.PENDING
        this.result = null
        this.reason = null
        // 用数组的原因是,同一个promise有可能同时有多个then回调,每一个都需要返回执行。
        this.onFullfilledCallbacks = []
        this.onRejectedCallbacks = []
        func(this.resolve.bind(this), this.reject.bind(this))
    }

    resolve(result) {
        setTimeout(() => {
            if (this.status === Promise2.PENDING) {
                this.status = Promise2.FULLFILLED
                this.result = result
                this.onFullfilledCallbacks.forEach((callback) => {
                    this.getCallbackFunc(callback)(this.result)
                })
            }
        })
    }

    reject(reason) {
        setTimeout(() => {
            if (this.status === Promise2.PENDING) {
                this.status = Promise2.REJECTED
                this.reason = reason
                this.onRejectedCallbacks.forEach((callback) => {
                    this.getCallbackFunc(callback)(this.reason)
                })
            }
        })
    }

    isFunction(func) {
        return Object.prototype.toString.call(func) === '[object Function]'
    }

    isObject(obj) {
        return Object.prototype.toString.call(obj) === '[object Object]'
    }

    handleResolvePromise(thenPromise, thenResult, resolve, reject) {
        if(thenPromise === thenResult){
            reject(new TypeError('Chaining cycle'))
        } else {
            if (thenResult instanceof Promise2) {
                let then = thenResult.then
                if (then && this.isFunction(then)) {
					// call的使用非常关键!!!,如果直接调用then,会报错
                    then.call(thenResult, resolve, reject)
                } else {
                    reject('errorrrr')
                }

            } else {
                resolve(thenResult)
            }
        }
        
    }

    getCallbackFunc(func) {
        return Object.prototype.toString.call(func) === '[object Function]' ? func : () => {}
    }

    then(onFullfilled, onRejected) {
        onFullfilled = this.getCallbackFunc(onFullfilled)
        onRejected = this.getCallbackFunc(onRejected)
        let thenPromise = new Promise2((resolve, reject) => {
            if (this.status === Promise2.PENDING) {
                // console.log(thenPromise)
                this.onFullfilledCallbacks.push(() => {
                    // 如果有后续的then,那么返回值应为一个Promise2。否则可以是任何其他值。
                    let thenResult = onFullfilled(this.result)
                    this.handleResolvePromise(thenPromise, thenResult, resolve, reject)
                })
                this.onRejectedCallbacks.push(() => {
                    let thenReason = onRejected(this.reason)
                    this.handleResolvePromise(thenPromise, thenReason, resolve, reject)
                })
            }
            if (this.status === Promise2.FULLFILLED) {
                let thenResult = onFullfilled(this.result)
                this.handleResolvePromise(thenPromise, thenResult, resolve, reject)
            }
            if (this.status === Promise2.REJECTED) {
                let thenReason = onRejected(this.reason)
                this.handleResolvePromise(thenPromise, thenReason, resolve, reject)
            }
        })
        return thenPromise
    }
}

let b = new Promise2((resolve, reject) => {
    console.log('exec promise')
    resolve('1')
    console.log('after resolve')
})
b.then((result) => {
    console.log('then 1')
    console.log(result)
    return new Promise2((resolve, reject) => {
        setTimeout(() => {
            resolve('then1 return')
        }, 1000)
    })
    // return 'then1 return'
}).then((result) => {
    console.log('then 2')
    console.log(result)
    return new Promise2((resolve, reject) => {
        setTimeout(() => {
            resolve('then2 return')
        }, 3000)
    })
    // return 'then2 return'
}).then((result) => {
    console.log('then 3')
    console.log(result)
})

console.log('end')

标签: javascript

添加新评论

0%