SOURCE

function PromiseA(executer) {
    let self = this;
    this.status = 'pending';
    this.value = undefined;
    this.reason = '';
    this.onFullfilledAll = [];
    this.onFiledAll = [];

    function resolve(value) {
        if (self.status === 'pending') {
            self.status = 'resolved'
            self.value = value;
            self.onFullfilledAll.forEach(fn => fn());
        }
    }

    function reject(reason) {
         if (self.status === 'pending') {
            self.status = 'rejected'
            self.reason = reason;
            self.onFiledAll.forEach(fn => fn());
         }
    }

    try {
        executer(resolve, reject);
    } catch(e) {
        reject(e)
    }
}

PromiseA.prototype.then = function(onFullfilled, onFiled) {
    let self = this;
    const promise2 = new PromiseA((resolve, reject) => {
         if (this.status === 'pending') {
            self.onFullfilledAll.push(() => {
                try{
                    const x = onFullfilled(self.value)
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e)
                }
            });
            self.onFiledAll.push(() => {
                try{
                    const x = onFiled(self.reason);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e)
                }
            });
        }
        if (this.status === 'resolved') {
            try{
                const x = onFullfilled(self.value);
                resolvePromise(promise2, x, resolve, reject);
            } catch (e) {
                reject(e)
            }
        }
        if (this.status === 'rejected') {
            try{
                const x = onFiled(self.reason)
                resolvePromise(promise2, x, resolve, reject);
            } catch (e) {
                reject(e)
            }
        }
    })
    return promise2;
};

function resolvePromise(promise2, x, resolve, reject) {
    if (promise2 === x) {
        return reject(new TypeError('循环调用'))
    }
    if (x !== null && (typeof x === 'Object' || typeof x === 'function')) {
        try{
            let then = x.then; 
            // 取对象上的属性 怎么能报异常呢?(这个promise不一定是自己写的 可能是别人写的 有的人会乱写)
            // x可能还是一个promise 那么就让这个promise执行即可
            // {then:{}}
            // 这里的逻辑不单单是自己的 还有别人的 别人的promise 可能既会调用成功 也会调用失败
            if(typeof then === 'function'){
                then.call(x,y=>{ // 返回promise后的成功结果
                    // 递归直到解析成普通值为止
                    // 递归 可能成功后的结果是一个promise 那就要循环的去解析
                    resolvePromise(promise2,y,resolve,reject);
                },err=>{ // promise的失败结果
                    reject(err);
                });
            }else{
                resolve(x);
            }
        }catch(e){
            reject(e);
        }
    } else {
        resolve(x)
    }
}

// let testPromise = new PromiseA((resolve, reject) => {
//     resolve('haha');
// });
// testPromise.then(data => {console.log(1, data)}, err => {console.log(2, data)});

let testPromise = new PromiseA((resolve, reject) => {
   setTimeout(() => {
       resolve('hah');
   }, 1000)
});
testPromise
    .then(data => {console.log(1, data);}, err => {console.log(11, data)})
    .then(data2 => {console.log(2, data2)}, err => {console.log(22, data2)})


Promise.all = function(promises) {
    return new Pomise((resovle, reject) => {
        const arr = [];
        const len = promises.length;
        promise.forEach((promise, index) => {
            promise.then((data) => {arr[index] = data}, reject);
            if (index++ === len) {
                resolve(arr);
            }
        })
    })
}

Promise.race = function(promises) {
    for(let i = 0,len = promises.length; i< len; i++){
        promises[i].then(data => {resolve(data), reject});
    }
}

Promise.resolve = function(value) {
    return new Promise((resovle, reject) => {resovle(value)})
}

Promise.reject = function(reason) {
    return new Promise((resovle, reject) => {reject(reason)})
}
console 命令行工具 X clear

                    
>
console