编辑代码

// 1.promise有三种状态(pednding、fullfilled、rejected)
// 2.promise的状态变化只有两种,且状态改变时
// 3.then回调内为异步任务时需要支持延迟执行resolve, reject
// 4.then方法支持链式调用
const PROMISE_STATE = {
    STATE_PENDING: "pending",
    STATE_FULLFILLED: "fullfilled",
    STATE_REJECTED: "rejected"
};
class myPromise {
    constructor(executor) {
        this.value = null;
        this.reason = null;
        this.state = PROMISE_STATE.STATE_PENDING;
        // 异步任务处理
        this.onFullfilledCallbacks = [];
        this.onRejectedCallbacks = [];
        // 执行出错时需要reject
        try {
            executor(this.resolve, this.reject);   
        } catch(e) {
            this.reject(e);
        }
    }
    resolve = value => {
        if (this.state === PROMISE_STATE.STATE_PENDING) {
            this.state = PROMISE_STATE.STATE_FULLFILLED;
            this.value = value;
            while(this.onFullfilledCallbacks.length) {
                this.onFullfilledCallbacks.shift()(value);
            }
        }
    }
    reject = reason => {
        if (this.state === PROMISE_STATE.STATE_PENDING) {
            this.state = PROMISE_STATE.STATE_REJECTED;
            this.reason = reason;
            while(this.onRejectedCallbacks.length) {
                this.onRejectedCallbacks.shift()(reason);
            }
        }
    }
    then(onFullfilled, onRejected) {
        if (this.state === PROMISE_STATE.STATE_FULLFILLED) {
            onFullfilled(this.value);
        } else if (this.state === PROMISE_STATE.STATE_REJECTED) {
            onRejected(this.reason);
        } else if (this.state === PROMISE_STATE.STATE_PENDING) {
            // 异步任务处理
            this.onFullfilledCallbacks.push(onFullfilled);
            this.onRejectedCallbacks.push(onRejected);
        }
    }
}

// 基础版测试
const promise = new myPromise((resolve, reject) => {
    // resolve("执行成功");
    reject("执行失败");
});
promise.then(value => {
  console.log('resolve', value)
}, reason => {
  console.log('reject', reason)
})

// 支持异步任务和多次调用测试
const promise1 = new myPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('success')
    }, 2000); 
});

promise1.then(value => {
  console.log(1)
  console.log('resolve', value)
});
 
promise1.then(value => {
  console.log(2)
  console.log('resolve', value)
});