zoukankan      html  css  js  c++  java
  • 浅谈用原生 JS 模仿个Promise 的实现

    在尝试写一个 Promise 的时候,没有看任何的开源代码,我觉得这样遇到的问题才足够真实。

    2018-05-15 11:10

    目前只能做到这样:

        const Promise  = function( callback ) {
            if(typeof callback !== 'function') {
                throw new Error(`Promise resolver ${ callback } is not a function`)
            }
    
            const PROMISE_STATUS = '[[PromiseStatus]]';
            const PROMISE_VALUE = '[[PromiseValue]]';
    
            this[PROMISE_STATUS] = 'pending';
            this[PROMISE_VALUE] = undefined;
    
            let resolveFn,
                rejectFn,
                isThen,
                isCatch,
                finallyFn;
    
            Object.defineProperty(this, PROMISE_STATUS, {
                set: ( newVal ) => {
                    const value = this[ PROMISE_VALUE ];
    
                    if( newVal === 'fulfilled' && isThen ) {
                        resolveFn && resolveFn( value )
                    }
    
                    if( newVal === 'rejected' && isCatch  ) {
                        rejectFn && rejectFn( value )
                    }
    
                    finallyFn && finallyFn( value )
                }
            });
    
            const resolve = ( response ) => {
                if( isCatch ) return;
                setTimeout(() => {
                    isThen = true;
                    this[ PROMISE_VALUE ] = response;
                    this[ PROMISE_STATUS ] = 'fulfilled';
                }, 0)
            };
    
            const reject = ( error ) => {
                if( isThen ) return;
                setTimeout(() => {
                    isCatch = true;
                    this[ PROMISE_VALUE ] = error;
                    this[ PROMISE_STATUS ] = 'rejected';
                }, 0)
                // const e = new Error( error );
                // e.stack = '';
                // e.name = '(in Promise)';
                // throw e
            };
    
            Promise.prototype.then = function ( callback ) {
                if( isCatch ) return;
                resolveFn = callback;
                return this;
            };
    
            Promise.prototype.catch = function ( callback ) {
                if( isThen ) return;
                rejectFn = callback;
                return this;
            };
    
            Promise.prototype.finally = function( callback ) {
                finallyFn = callback;
                return this;
            };
    
            callback( resolve, reject );
        };

    这里是借鉴了 Vue 双向数据绑定的实现方法,在状态改变的时候执行对应的 then / catch / finally 方法。

    但是这里没办法链式调用,遇到了一个矛盾的地方。下面的示例仅仅按 .then().catch().finally() 这样调用的顺序讲

    1、then 方法如果不返回实例本身,那么 catch 和 finally 方法就没办法链式调用,因为 this 的指向不是原实例了。

    2、then 方法如果返回实例本身,那么 .then().then() 第二次 then 方法的 this 那依然只是那一个实例,这里应该是,如果上一次 then 方法的返回值是一个 Promise 则是这个 Promise,如果不是 Promise,则是一个新的 Promise。

    所以冲突了,我决定再想想,如果想不出来就只能去参考源码了。

  • 相关阅读:
    分段随机实践—模拟线上流量
    基于docker的分布式性能测试框架功能验证(二)
    将博客搬家至CSDN
    考研机试 98.棋盘游戏
    考研机试 100.路径打印
    考研机试 102.计算表达式
    考研机试 97.数字反转
    考研机试 90.简单密码
    考研机试 87.鸡兔同笼
    考研机试 79.浮点数加法
  • 原文地址:https://www.cnblogs.com/xwant/p/9042244.html
Copyright © 2011-2022 走看看