Promise的源码记录

Promise 源码记录(上课过程记录的笔记)

Promise.js代码:

仅仅实现了简单的then,catch和Promise对象的执行器函数

(function (window){   /** IIFE */
    const PENDING ='pending';
    const RESOLVED ='resolved';
    const REJECTED = 'rejected';
    function Promise(exector){
        let self = this;
        self.status = PENDING;
        /**
         * callbacks里面存储的数据类型为:{onResolved,onRejected}
         */
        self.callbacks = [];
        self.data = undefined;
        function resolve(value){
            if(self.status === PENDING){
                self.data = value;
                self.status = RESOLVED;
                if(self.callbacks.length > 0){
                    self.callbacks.forEach(callbackObj => {
                        setTimeout(() => {
                            callbackObj.onResolved(value);
                        });
                    });
                }
                
            }
        }
        function reject(reasen){
            if(self.status === PENDING){
                self.data = reasen;
                self.status = REJECTED;
                if(self.callbacks.length > 0){
                    self.callbacks.forEach(callbackObj => {
                        setTimeout(() => {
                            callbackObj.onRejected(reason);
                        });
                    });
                }
            }
        }
        try{
            exector(resolve,reject);
        }catch(error){
            reject(error);
        }
    }

    /** 
     * 定义Promise的then方法实现回调
     */
    Promise.prototype.then = function(onResolved, onRejected){
        /**首先定义两个回调函数的形式
         * 1. 如果两个回调时函数,则直接返回
         * 2. 如果两个回调函数不是函数类型,强制其为函数
         */
        onResolved = typeof onResolved === 'function' ? onResolved : value => value;
        onRejected = typeof onRejected === 'function' ? onRejected : reasen => {throw reason};
        const self = this;
        return new Promise((resolve, reject) => {
            /** 直接将RESOLVED/REJECTED状态下的执行器封装成一个函数 */
            function handle(callback){
                /** 这里要把执行函数放入异步队列中 */
                /**
                 * 此处要定义Promise的状态,分为三种情况
                 * 1. 抛出异常,直接执行reject
                 * 2. 返回的值是Promise,则新的Promise的结果和状态由上一次的结果决定
                 * 3. 返回的值不是Promise,则新的Promise直接成功
                 */
                try {
                    const result = callback(self.data);
                    if(result instanceof Promise){
                        result.then(resolve, reject);
                    }else{
                        resolve(result);
                    }
                } catch (reason) {
                    reject(reason);
                }
            }
            /**
             * 新的Promise的状态要根据onResolved/onRejected的执行结果来决定
             */
            if(self.status === RESOLVED){
                setTimeout(() => {
                    handle(onResolved);
                });
            }else if(self.status === REJECTED){
                setTimeout(() => {
                    handle(onRejected);
                });
            }else{
                /**
                 * 如果是PENDING状态,要把回调函数保存起来
                 * 但是不能直接去存,因为要根据之前的结果来定义新的Promise的状态
                 * 下面不需要异步调用,因为异步操作在Promise的执行器中已经做了
                 */
                self.callbacks.push({
                    onResolved(){
                        handle(onResolved);
                    },
                    onRejected(){
                        handle(onRejected);
                    }
                });
            }
        });
    }

    /** 定义catch方法 */
    Promise.prototype.catch = function(onRejected){
        this.then(undefined, onRejected);
    }
    /** 向外暴露Promise */
    window.Promise = Promise
})(window)

测试用的index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Promise</title>
    <script src="./Promise.js"></script>
</head>
<body>
    <script type="text/javascript">
        const p1 = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(5);
            }, 3000);
        });
        p1.then(value => {
            console.log("The anwser is successful, and the result is :", value);
            return new Promise(() => {});
        }).then(value => {
            console.log("The next result is:", value);
        }).catch(error => {
            console.log("The error is :", error)
        });
    </script>
</body>
</html>
发布了17 篇原创文章 · 获赞 0 · 访问量 467

猜你喜欢

转载自blog.csdn.net/chizhonghang/article/details/105297418
今日推荐