简易版promise

107 阅读1分钟
function MyPromise(fn) {    
    const pending = 'pending', resolved = 'resolved', rejected = 'rejected';    
    const that = this;    
    const value = null;    
    const resolvedCallbackList = [], rejectCallbackList = [];    
    that.value = value;    
    that.statusMap = {        
        pending,        
        resolved,        
        rejected    
    }    
    that.status = pending;    
    that.resolvedCallbackList = resolvedCallbackList;    
    that.rejectCallbackList = rejectCallbackList;    
    function resolve(v) {        
        if (that.status === pending) {            
            if (v instanceof MyPromise) {                
                return v.then(resolve, reject)            
            }            
            that.value = v;            
            that.status = resolved;            
            setTimeout(() => {                
                that.resolvedCallbackList.forEach(f => {                    
                    try {                        
                        f(v)                    
                    } catch(e) {                        
                        reject(e)                    
                    }                
                })            
            })        
        }    
    }    
    function reject(v) {        
        if (that.status === pending) {            
            that.value = v;            
            that.status = rejected;            
            setTimeout(() => {                
                that.rejectCallbackList.forEach(f => {                    
                    try {                        
                        f(v)                    
                    } catch(e) {                        
                        reject(e)                    
                    }                
                })            
            })        
        }    
    }    
    try {        
        fn(resolve, reject)    
    } catch(e) {        
    reject(e)    
}}    

MyPromise.prototype.then = function(onFulfilled = v => v, onRejected = err => err) {    
    const that = this;    
    let newPromise;    
    if (that.status === that.statusMap.pending) {        
        newPromise = new MyPromise(function(resolve, reject) {            
            that.resolvedCallbackList.push(() => {                
                resolve(onFulfilled(that.value))            
            });            
            that.rejectCallbackList.push(() => {                
                reject(onRejected(that.value))            
            });        
        })    
    };    

    if (that.status === that.statusMap.resolved) {        
        newPromise = new Promise(function(resolve, reject) {            
            resolve(onFulfilled(that.value))        
        })    
    }    

    if (that.status === that.statusMap.rejected) {        
        newPromise = new Promise(function(resolve, reject) {            
            reject(onRejected(that.value))        
        })    
    }    
    return newPromise;
}

MyPromise.all = function promiseAll(promises) {    
    return new MyPromise(function(resolve, reject) {        
        var resolvedCounter = 0; // 已经resolved的个数      
        var promiseNum = promises.length;        
        var resolvedValues = new Array(promiseNum);        
        for (let i = 0; i < promiseNum; i++) {            
            promises[i].then(function(value) {                
                resolvedCounter++                
                resolvedValues[i] = value                
                if (resolvedCounter == promiseNum) { // 当所有都变为resolved时                  
                    return resolve(resolvedValues)                
                }                
            }, function(reason) {                
                return reject(reason)            
                })        
            }    
        })}

MyPromise.resolve = function(v) {    
    return new MyPromise(function(res, rej) {        
        res(v)    
})}