2019-06-16 手写简易promise(妙味王允)

2019-06-16  本文已影响0人  DreamNeverDie

customPromise.js

;(function(){

    const status = {
        pending: 0,
        fulfilled: 1,
        rejected: 2
    }

    class CustomePromise{
        constructor(func){
            // 初始状态
            this._status = status.pending;
            this._value = null;  // 记录resolve函数传入的参数
            this._error = null;  // 记录reject函数传入的参数

            // 收集成功状态要执行的函数
            this.resolvedArr = [];
            // 收集失败状态要执行的函数
            this.rejectedArr = [];

            this._handler(func)
        }
        // 判断value有没有then函数,并且拿出then函数
        _getThen(value){
            let type = typeof value;
            if(value && (type === 'object' || type === 'function')){
                let then;
                if(then = value.then){
                    return then;
                }
            }

            return null;
        }
        // 接收外部传入的函数,调用外部传入的函数
        _handler(func){
            let done = false; // 就是让函数值执行一次
            func((value) => {
                if(done) return;
                done = true;

                // value有没有then函数
                let then = this._getThen(value);
                if(then){
                    // 拿到对象的then之后,怎么知道这个promise对象完成了呢?
                    // 在then函数上注册成功和失败函数就可以
                    return this._handler(then.bind(value))
                }

                this._resolve(value);
            },(error) => {
                if(done) return;
                done = true;
                // value有没有then函数
                let then = this._getThen(error);
                if(then){
                    // 拿到对象的then之后,怎么知道这个promise对象完成了呢?
                    // 在then函数上注册成功和失败函数就可以
                    return this._handler(then.bind(error))
                }
                this._reject(error);
            });
        }

        _resolve(value){
            
            setTimeout(() => {
                // 把状态改为成功
                this._status = status.fulfilled;
                this._value = value;
                // 执行所有成功的函数
                this.resolvedArr.forEach(item => {
                    item(this._value)
                })
            })
        }
        _reject(error){
            setTimeout(() => {
                // 把状态改为失败
                this._status = status.rejected;
                this._error = error;

                this.rejectedArr.forEach(item => item(this._error));
            })
        }
        // 收集注册的成功状态或失败状态要执行的函数
        _done(resolvedFunc,rejectedFunc){
            //pending的时候收集
            resolvedFunc = typeof resolvedFunc === 'function' 
                            ? resolvedFunc : null;
            rejectedFunc = typeof rejectedFunc === 'function' 
                            ? rejectedFunc : null;

            // 收集
            if(this._status === 0){
                if(resolvedFunc) this.resolvedArr.push(resolvedFunc);
                if(rejectedFunc) this.rejectedArr.push(rejectedFunc);
            }else if(this._status === 1 && resolvedFunc){ // 直接执行
                resolvedFunc(this._value);
            }else if(this._status === 2 && rejectedFunc){
                rejectedFunc(this._error);
            }
        }

        // 收集注册的成功状态或失败状态要执行的函数
        // 返回一个promise对象
        then(resolvedFunc,rejectedFunc){
            //this._done(resolvedFunc,rejectedFunc)
            return new CustomePromise((resolve,reject) => {
                this._done(
                    (value) => {
                        // resolvedFunc不是一个函数
                        if(typeof resolvedFunc !== 'function'){
                            return resolve(value);
                        }
                        resolve(resolvedFunc(value));
                    },
                    (error) => {
                        if(typeof rejectedFunc !== 'function'){
                            return reject(error);
                        }
                        reject(rejectedFunc(error))
                    }
                )
            })
        }
    }

    window.CustomePromise = CustomePromise;

})();

使用自己写的CustomePromise

<!DOCTYPE html>
<html lang="zh-cn">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title></title>
        <style>
            
        </style>
        <script src="./customePromise.js"></script>
<script>
    // new Promise返回的对象称之为Promise对象
    /*
        三种状态:
            pending 正在进行
            fulfilled 已完成
            rejected 已失败

        1. new Promise 接收一个函数 executor
        2. 函数 executor 接收两个参数,resolve,reject
            调用resolve的时候,把promise对象转成成功状态
            调用reject的时候,把promise对象转成失败状态
        3. promise对象的then方法来注册成功状态或者失败状态要执行的函数
            p.then(resolveFunc,rejectFunc);
            p.then(resolveFunc,rejectFunc);
            p.then(resolveFunc,rejectFunc);
            p.then(resolveFunc,rejectFunc);

            实现是一个promise对象调用多次then方法

        5. then函数的链式操作
            p.then().then().then();

            就是then函数执行后返回一个promise对象

        6. thenable
            拥有 then 方法的对象或函数
            {
                then(){}
            }

            promise对象也拥有then方法

        7. 当给resolve传入一个promise对象的时候,只有等到promise对象装成成功或者失败,resolve才会成功

        8.resovle要接受的参数
            1. 简单值
            2. 接收thenable对象

        9.then中成功或失败执行的函数的返回值
            1. 有简单类型返回值,作为then方法返回的promise对象的成功状态的值
        
            2. 当返回一个thenable对象的时候,只有是成功状态才能执行下一个then

    */


    let p = new CustomePromise((resolve,reject) => {
        setTimeout(function (){
            resolve('成功');  
        },1000) 
    });

    p.then((data) => {
            console.log('第一个then成功',data)
            return new Promise((resolve) => {
                setTimeout(() => {
                    resolve('延迟了5000')
                },5000)
            })
        }).then((data) => {
            console.log('第2个then',data)
        })
        .then(123)
        .then((data) => {
            console.log('第4个then',data)
        });
</script>
    </head>

    <body>
        
    </body>
</html>
上一篇下一篇

猜你喜欢

热点阅读