then 链式写法

142 阅读1分钟

const { threadId } = require("worker_threads");

// 定义Promise的三种状态 const PENDING = 'PENDING'; // pending就是未决, const FULFILLED = 'FULFILLED'; // resolve可以理解为成功, const REJECTED = 'REJECTED'; // reject可以理解为拒绝。

class MyPromise { constructor(excutor) { excutor(this.resolve, this.reject) }

resolveValue = undefined
rejectValue = undefined
resolveHandlerCache = [] // 初始值设为数组, 因为同一个Promise实例可多次调用 then父方法
rejectHandlerCache = []
status = PENDING

resolve = (val) => {
    if (this.status !== PENDING) return
    this.resolveValue = val
    this.status = FULFILLED
    while (this.resolveHandlerCache.length) {
        this.resolveHandlerCache.pop()()
    }
}

reject = (val) => {
    if (this.status !== PENDING) return
    this.rejectValue = val
    this.status = REJECTED
    while (this.rejectHandlerCache.length) {
        this.rejectHandlerCache.pop()()
    }
}

then(successHandler, rejectHandler) {
    let result = new MyPromise((resolve, reject) => {
        setTimeout(() => {
            if (this.status === FULFILLED) {
                let res = successHandler(this.resolveValue)
                handeThen(res, resolve, reject)
            } else if (this.status === REJECTED) {
                rejectHandler(this.rejectValue)
            } else {
                this.resolveHandlerCache.push(() => {
                    let res = successHandler(this.resolveValue);
                    handeThen(res, resolve, reject)
                })
                this.rejectHandlerCache.push(() => {
                    rejectHandler(this.rejectValue)
                })
            }
        }, 0)
    });

    return result;
}

} function handeThen(res, resolve, reject) { if (res instanceof MyPromise) { res.then(resolve, reject) } else { resolve(res) } }

let myp = new MyPromise((resolve) => { setTimeout(() => { resolve(123) }) }).then(res => { console.log('123', res) return new MyPromise(resolve => { setTimeout(() => { resolve(789) }, 200) }) }).then(res => { console.log('456', res) return 101 }).then(res => { console.log('101', res) return new MyPromise(resolve => { setTimeout(() => { resolve(120) }, 100) }) }).then(res => { console.log('120', res) return 101 })