# promise实现

// 准备状态
const STATUS_PENDING = 'pending';
// 解决状态
const STATUS_RESOLVED = 'resolved';
// 拒绝状态
const STATUS_REJECTED = 'rejected';

// 检测数据类型
const isType = type => obj => Object.prototype.toString.call(obj) === `[object ${type}]`;
// 是否函数
const isFunction = isType('Function');

class A {
    constructor(func) {
        if (!isFunction(func)) {
            console.error('the constructor param must be function');
            return;
        }
        // 状态
        this.status = STATUS_PENDING;
        // 解决回调列表
        this.onFulfilledList = [];
        // 拒绝回调列表
        this.onRejectedList = [];
        try {
            // 执行自执行函数
            func(this.setResolve.bind(this), this.setReject.bind(this));
        } catch(e) {
            this.setReject(e);
        }
    }
    
    /**
     * 设置解决回调
     * @param {*} val 
     */
    setResolve(val) {
        if (this.status === STATUS_PENDING) {
            // 修改状态
            this.status = STATUS_RESOLVED;
            // 异步执行 防止同步执行promise无效
            setTimeout(() => {
                this.onFulfilledList.forEach(it => it(val));
            });
        }
    }

    /**
     * 设置拒绝回调
     * @param {*} val 
     */
    setReject(val) {
        if (this.status === STATUS_PENDING) {
            // 修改状态
            this.status = STATUS_REJECTED;
            // 异步执行 防止同步执行promise无效
            setTimeout(() => {
                this.onRejectedList.forEach(it => it(val));
            });
        }
    }

    then(onFulfilled, onRejected) {
        if (isFunction(onFulfilled)) {
            this.onFulfilledList.push(onFulfilled);
        }
        if (isFunction(onRejected)) {
            this.onRejectedList.push(onRejected);
        }
        return this;
    }

    catch(onRejected) {
        if (isFunction(onRejected)) {
            this.onRejectedList.push(onRejected);
        }
        return this;
    }
}

// 测试样例
// 异步测试
new A((resolve, reject) => {
    setTimeout(() => {
        resolve()
    }, 2000)
})
.then((result) => {
    console.log(result)
});

// 拒绝状态,异常捕获
new A((resolve, reject) => {
    reject('执行 reject')
}).then((result) => {
    console.log(result, 'then');
}).catch((result) => {
    console.log(result, 'catch');
});

// 执行多次then
new A((resolve, reject) => {
    setTimeout(() => {
        resolve(123)
    }, 2000)
}).then((result) => {
    console.log(result, 'result');
}).then((result) => {
    console.log(result, 'result 122');
});