Promise原理理解

使用了很久promise方法来解决异步编程问题,今天抽空总结一下promise的设计原理,解释的不好,欢迎指点出来。

1.promise只有两种结果:pending=>resolved(成功),pending=>rejected(失败),状态一旦改变,就不能在改变;

2.then 接收成功返回的值

3.catch接收失败放回的值

在没有promise之前,基本上用callback来解决一个方法执行完后在执行,如果有多个就嵌套多个callback,代码就显得非常臃肿,

而.then .catch模式会让代码逻辑变的清晰,看起来同步模式,其实是异步的。

1.创建class  对象模板,在里面constructor(){} 定义初始的变量,也定义then 和catch 的方法

class Promise {
    constructor(fn) {
        this.status = statusMap.PENDING; // 初始状态
        this.value = undefined; // 成功的值
        this.reason = undefined; // 失败的值
        this.fulfilledCbs = []; // then fulfilled callback
        this.rejectedCbs = [];  // 失败后运行的脚本
        try {
            fn((value) => {
                resolvePromise(this, value);  // 解析
            }, (reason) => {
                rejectedPromise(this, reason); // 失败的处理
            })
        } catch (error) {
            rejectedPromise(this, error); //失败处理
        }        
    }    
    then(onFulfilled,onReject){  
        // .then 成功里面接收回调的值
    }    
    catch(onReject){ 
        // .catch 失败里面接收回调的值
    }
}

2.接下来展开then方法里的判断status状态处理

then(onFulfilled, onRejected) {
        const promise1 = this;
        const promise2 = new Promise(() => { });
        onFulfilled = isFunction(onFulfilled) ? onFulfilled : (value) => { return value }; // 设置默认值
        onRejected = isFunction(onRejected) ? onRejected : (err) => { throw err }; 
        // 成功 
        if (promise1.status === statusMap.FULFILLED) {  
            isFunction(onFulfilled) && setTimeout(() => {
                try {
                    const x = onFulfilled(promise1.value); 
                    resolvePromise(promise2, x);  // 决议
                } catch (error) {
                    rejectedPromise(promise2, error);
                }
            }, 0);

        }
        // 失败
        if (promise1.status === statusMap.REJECTED) { 
            isFunction(onRejected) && setTimeout(() => {
                try {
                    const x = onRejected(promise1.reason);
                    resolvePromise(promise2, x); // 决议
                } catch (error) {
                    rejectedPromise(promise2, error);
                }
            }, 0);

        }
        // 进行中,向fulfilledCbs和rejectedCbs push函数方法
        if (promise1.status === statusMap.PENDING) { 
            isFunction(onFulfilled) && promise1.fulfilledCbs.push((val) => {
                setTimeout(() => {
                    try {
                        const x = onFulfilled(val); // 决议
                        resolvePromise(promise2, x);
                    } catch (error) {
                        rejectedPromise(promise2, error);
                    }
                }, 0)
            })
            isFunction(onRejected) && promise1.rejectedCbs.push((err) => {
                setTimeout(() => {
                    try {
                        const x = onRejected(err); // 决议
                        resolvePromise(promise2, x);
                    } catch (error) {
                        rejectedPromise(promise2, error);
                    }
                }, 0)
            })
        }
        return promise2;
    }

3.catch里就直接调用then就可以

catch(onRejected){
        return this.then(undefined,onRejected);
 }

4.在then里面有个resolvePromise决议方法,是处理在promise的resove和reject里传递的是值、对象、function、new promise的

// promise 解析
function resolvePromise(promise, x) {
    if (promise === x) {
        rejectedPromise(promise, new TypeError('cant be the same'))
        return;
    }
    if (isPromise(x)) {
        if (x.status === statusMap.FULFILLED) {
            fulfilledPromise(promise, x.value);
            return;
        }
        if (x.status === statusMap.REJECTED) {
            rejectedPromise(promise, x.reason);
            return;
        }
        if (x.status === statusMap.PENDING) {
            x.then(() => {
                fulfilledPromise(promise, x.value);
                // return;
            }, () => {
                rejectedPromise(promise, x.reason);
                // return;
            })
            return;
        }
        return;
    }
    // 是对象或函数
    if ( x !== null  && (isObject(x) || isFunction(x))) {
        let then;
        let called = false; // promise的状态只能pending->fulfilled;pending->rejected;
        try {
            then = x.then;
        } catch (error) {
            rejectedPromise(promise, error);
            return;
        }
        if (isFunction(then)) {
            try {
                then.call(x, (y) => {
                    if (called) {
                        return;
                    }
                    called = true;
                    resolvePromise(promise, y);
                    // fulfilledPromise(promise.y);
                }, (r) => {
                    if (called) {
                        return;
                    }
                    called = true;
                    rejectedPromise(promise, r);
                })
            } catch (error) {
                if (called) {
                    return;
                }
                called = true;
                rejectedPromise(promise, error);
            }
            return;
        } else {
            if (called) {
                return;
            }
            called = true;
            fulfilledPromise(promise, x);
            return;
        }
    } else { // 不是对象或函数
        fulfilledPromise(promise, x);
        return;
    }
}

5.最后贴上全部的代码

const statusMap = {
    PENDING: 'pending',
    FULFILLED: 'fulfilled',
    REJECTED: 'rejected',
}
// 将promise设置为fulfilled状态
function fulfilledPromise(promise, value) {
    if (promise.status !== 'pending') {
        return;
    }
    promise.status = statusMap.FULFILLED;
    promise.value = value;
    runCbs(promise.fulfilledCbs, value)
}
// 将promise设置为rejected状态
function rejectedPromise(promise, reason) {
    if (promise.status !== 'pending') {
        return;
    }
    promise.status = statusMap.REJECTED;
    promise.reason = reason;
    runCbs(promise.rejectedCbs, reason)
}
function isFunction(fn) {
    return Object.prototype.toString.call(fn).toLocaleLowerCase() === "[object function]";
}
function isPromise(p) {
    return p instanceof Promise;
}
function isObject(o) {
    return Object.prototype.toString.call(o).toLocaleLowerCase() === "[object object]";
}
function runCbs(cbs, value) {
    cbs.forEach(cb => cb(value));
}

// promise 解析
function resolvePromise(promise, x) {

    if (promise === x) {
        rejectedPromise(promise, new TypeError('cant be the same'))
        return;
    }
    if (isPromise(x)) {
        if (x.status === statusMap.FULFILLED) {
            fulfilledPromise(promise, x.value);
            return;
        }
        if (x.status === statusMap.REJECTED) {
            rejectedPromise(promise, x.reason);
            return;
        }
        if (x.status === statusMap.PENDING) {
            x.then(() => {
                fulfilledPromise(promise, x.value);
             }, () => {
                rejectedPromise(promise, x.reason);
               
            })
            return;
        }
        return;
    }
    // 是对象或函数
    if ( x !== null  && (isObject(x) || isFunction(x))) {
        let then;
        let called = false;
        try {
            then = x.then;
        } catch (error) {
            rejectedPromise(promise, error);
            return;
        }
        if (isFunction(then)) {
            try {
                then.call(x, (y) => {
                    if (called) {
                        return;
                    }
                    called = true;
                    resolvePromise(promise, y);
                    // fulfilledPromise(promise.y);
                }, (r) => {
                    if (called) {
                        return;
                    }
                    called = true;
                    rejectedPromise(promise, r);
                })
            } catch (error) {
                if (called) {
                    return;
                }
                called = true;
                rejectedPromise(promise, error);
            }
            return;
        } else {
            if (called) {
                return;
            }
            called = true;
            fulfilledPromise(promise, x);
            return;
        }
    } else { // 不是对象或函数
        fulfilledPromise(promise, x);
        return;
    }
}
class Promise {
    constructor(fn) {
        this.status = statusMap.PENDING;
        this.value = undefined;
        this.reason = undefined;
        this.fulfilledCbs = []; // then fulfilled callback
        this.rejectedCbs = [];
        try {
            fn((value) => {
                resolvePromise(this, value);
            }, (reason) => {
                rejectedPromise(this, reason);
            })
        } catch (error) {
            rejectedPromise(this, error);
        }        
    }
    then(onFulfilled, onRejected) {
        const promise1 = this;
        const promise2 = new Promise(() => { });
        onFulfilled = isFunction(onFulfilled) ? onFulfilled : (value) => { return value }; // 设置默认值
        onRejected = isFunction(onRejected) ? onRejected : (err) => { throw err };       
        if (promise1.status === statusMap.FULFILLED) {
            isFunction(onFulfilled) && setTimeout(() => {
                try {
                    const x = onFulfilled(promise1.value); 
                    resolvePromise(promise2, x);  // 决议
                } catch (error) {
                    rejectedPromise(promise2, error);
                }
            }, 0);

        }
        if (promise1.status === statusMap.REJECTED) {
            isFunction(onRejected) && setTimeout(() => {
                try {
                    const x = onRejected(promise1.reason);
                    resolvePromise(promise2, x); // 决议
                } catch (error) {
                    rejectedPromise(promise2, error);
                }
            }, 0);

        }
        if (promise1.status === statusMap.PENDING) {
            isFunction(onFulfilled) && promise1.fulfilledCbs.push((val) => {
                setTimeout(() => {
                    try {
                        const x = onFulfilled(val); // 决议
                        resolvePromise(promise2, x);
                    } catch (error) {
                        rejectedPromise(promise2, error);
                    }
                }, 0)
            })
            isFunction(onRejected) && promise1.rejectedCbs.push((err) => {
                setTimeout(() => {
                    try {
                        const x = onRejected(err); // 决议
                        resolvePromise(promise2, x);
                    } catch (error) {
                        rejectedPromise(promise2, error);
                    }
                }, 0)
            })
        }
        return promise2;
    }
    catch(onRejected){
        return this.then(undefined,onRejected);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值