【Promise源码学习】-完整篇

48 阅读1分钟
const PENDING = 'pending'; 
const FULFILLED = 'fulfilled'; 
const REJECTED = 'rejected';
class _Promise {
    constructor(exc) {
        this._status = PENDING;
        this._value = undefined;
        this.resolveQue = [];
        this.rejectQue = [];
        const _resolve = (val)=> {
            const run = () => {
                if(this._status!==PENDING) return;
                this._status = FULFILLED;
                this._value = val;
                while(this.resolveQue.length) {
                    const cb = this.resolveQue.shift();
                    cb(val);
                }
            }
            setTimeOut(run)
        }
        const _reject = (reason)=> {
            const run = () => {
                if(this._status!==PENDING) return;
                this._status=REJECTED;
                this._value = reason;
                while(this.rejectQue.length) {
                    const cb = this.rejectQue.shift();
                    cb(reason);
                }
            }
            setTimeOut(run)
        }
        try {
            exc(_resolve,_reject)
        } catch (error) {
            reject(error);
        }
        
    }
    then(resolveFn,rejectFn) {
        // 根据规范,如果then的参数不是function,则我们需要忽略它, 让链式调用继续往下执行 
        typeof resolveFn !== 'function' ? resolveFn = value => value : null 
        typeof rejectFn !== 'function' ? rejectFn = reason => { throw new 
            Error(reason instanceof Error? reason.message:reason); } : null
        return new Promise((resolve,reject)=>{
            const fulFn = (value) => {
                try {
                    let x = resolveFn(value);
                    x instanceof _Promise ? x.then(resolve,reject) : resolve(x);
                } catch (error) {
                    reject(error)
                }
            }
            const rejFn = (value) => {
                try {
                    let x = rejectFn(value);
                    x instanceof _Promise ? x.then(resolve,reject) : resolve(x)
                } catch (error) {
                    reject(error)
                }
            }
            switch(this._status)
                case: PENDING
                    this.resolveQue.push(fulFn);
                    this.rejectQue.push(rejFn);
                    break;
                case: FULFILLED
                    fulFn(this._value);
                    break;
                case: REJECTED
                    rejFn(this._value);
                    break;
        })
    }
    catch(rejectFn) {
        return this.then(undefined, rejectFn);
    }
    all(promiseArr) {
        return new Promise((resolve,reject) => {
            let i = 0,
            result = [];
            promiseArr.forEach((p,j) => {
                _Promise.resolve(p).then( res => {
                    if(i === promiseArr.length) resolve(result);
                    i++;
                    result[j] = res;
                }, err => reject(err))
            })
        })
    }
    // 返回一个在所有给定promise都fulfilled或rejected后的promise
    allSetted(promiseArr) {
        return new Promise((resolve,reject) => {
            let i = 0,
            result = [];
            promiseArr.forEach((p,j) => {
                _Promise.resolve(p).then( res => {
                    if(i === promiseArr.length) resolve(result);
                    i++;
                    result[j] = {status: 'fulfilled', value: res};
                })
                .catch(err) {
                    if(i === promiseArr.length) resolve(result);
                    i++;
                    result[j] = {status: 'rejected', reason: err};
                }
            })
        })

    }
    race(promiseArr) {
        return new _Promise((resolve, reject) => {
            for(let p of promiseArr) {
                _Promise.resolve(p).then(res => {
                    resolve(res);
                }, err => reject(err))
            }
        })
    }
    // 执行所有 promise,使用最先返回的成功结果;全部失败才判定为失败; `p.then("谁先成功就返回谁","失败了先存起来,都失败了才返回")`
    any(promiseArr) {
        let i =0 , rejectsArr = [];
        return new _Promise((resolve, reject) => {
            promiseArr.forEach(p, j) {
                _Promise.resolve(p).then(res => {
                    resolve(res);
                }, err => {
                    i++
                    rejectsArr[j] = err;
                    if(i === promiseArr.length) reject(rejectsArr);
                })
            })
        })
    }
    finally(callback) {
        return this.then(value=>{
            _promise.resolve(callback()).then(() => value)
        },reason=> {
            _Promise.resolve(callback()).then(() => { throw reason })
        })
    }
    static resolve(value) {
        if(value instanceof _Promise) return value;
        return new _Promise((resolve, reject) => {
            resolve(value);
        })
    }
}

juejin.cn/post/684490… juejin.cn/post/702748…