最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Promise 系列(1)-- 核心逻辑实现

    正文概述 掘金(大怪腿长一米八)   2021-04-07   527

    拆解 Promise 的使用:

    1. 在使用一个 Promise 的时候,需要通过一个 new 关键字来创建一个 Promise 对象;
    new Promise();
    

    在创建完成之后,可以看出这个 Promise 就是一个(MDN参考:developer.mozilla.org/zh-CN/docs/… )

    1. 在执行这个类的时候,需要传递一个回调函数进来,这个回调函数会立即执行(见下图)。也就是说在创建了 Promise 之后,这个回调函数是会被立即执行的(这好像是句废话)。
    new Promise(() => {});
    

    Promise 系列(1)-- 核心逻辑实现

    1. 在使用 Promise 的时候会向里面传递两个参数:resolvereject;调用这两个参数的时候会更改 Promise 的状态,所以这两个参数实际上是两个函数。
    new Promise((resolve, reject) => {});
    
    1. Promise 的状态:等待 pending; 失败 rejected; 成功 fulfilled;
    new Promise(() => {
        resolve('成功');
        // reject('失败');
    });
    // Promise 的状态改变:一旦状态确定就不可更改
    // resolve 被调用时将状态会更改为成功:pending -> fulfilled
    // reject  被调用时将状态会更改为失败:pending -> rejected
    
    PS:是不是好奇凭啥 resolve 出来的就是成功,reject 出来的就是失败,反过来用不行么? 我觉得行!但是没招儿,这甲鱼的屁股--规定!
    1. 在使用 Promise 的时候还可以将 Promise 执行的结果赋值给一个变量,在这里还可以调用 Promise 的方法 then;由此可见 then 方法里面干了一件事儿,就是判断了当前这个 Promise 的状态,如果是成功就调用成功的回调,如果是失败就调用失败的回调
    let promise = new Promise(() => {
        resolve('成功');
        // reject('失败');
    });
    
    // 调用 Promise 的方法 then;成功 失败
    promise.then(() => {}, () => {});
    
    1. then 方法成功回调有一个参数,表示成功的值,失败同样也有一个参数,表示失败的原因
    let promise = new Promise(() => {
        resolve('成功');
        // reject('失败');
    });
    
    // 调用 Promise 的方法 then;成功传递成功的值,失败传递失败的原因
    promise.then(value => {}, reason => {});
    

    拆解分析结束,开始实现一个 Promise

    1. 既然 Promise 是一个,那就用 class 关键字来创建一个
    class myPromise {}
    
    1. 在这个类执行的时候,需要传递回调函数进来,所以这里通过构造函数 constructor 来接收这个回调函数。
    class myPromise {
        constructor(executor) {
            executor();
        }
    }
    
    1. 在这个回调函数被调用的时候又传递了resolve函数reject函数
    class myPromise {
        constructor(executor) {
            executor(this.resolve, this.reject);
        }
        // Q: 为啥要写成箭头函数?
        // A1: 这两个函数在被调用的时候是直接被调用的,如果这两个函数是一个普通函数的情况下,这两个函数里面的 this 就指向了 window 或者 undefined;
        // A2: 定义为箭头函数就是让 this 的指向就指向当前的实例对象,也就是创建的这个 Promise 对象
        resolve = () => {};
        reject = () => {};
    }
    
    1. 当调用 resolve 的时候需要将 Promise 的状态更改为成功,当调用 reject 的时候需要将 Promise 的状态更改为失败。
    // 更改状态就要有状态 (真理啊!)
    const PENDING = 'pending';
    const FULFILLED = 'fulfilled';
    const REJECTED = 'reiected';
    // Q: 为啥定义成常量?  // A: 频繁使用方便复用
    
    class myPromise {
        constructor(executor) {
            executor(this.resolve, this.reject);
        }
        // 因为这个状态是每一个 Promise 独有的状态,所以在这里定义成一个实例属性
        status = PENDING;
        resolve = () => {
            // 将状态更改为成功
            this.status = FULFILLED;
        };
        reject = () => {
            // 将状态更改为失败
            this.status = REJECTED;
        };
    }
    
    PS: 凭啥 resolve 就得是成功,就让 reject 是成功不行么?都自己写了还不能做主?行!可以!没问题!写程序嘛,开心就好。
    1. Promise 状态一经更改就不能再次改变,按照上面的写法调用了成功回调之后紧接着调用失败回调,那么这个成功又失败了,所以这个实现是存在问题的(白给,写了一堆还有问题,这是写了个寂寞啊)为了防止它在成功和失败之间反复横跳,更改这个状态的时候给它加个判断试试
    const PENDING = 'pending';
    const FULFILLED = 'fulfilled';
    const REJECTED = 'reiected';
    
    class myPromise {
        constructor(executor) {
            executor(this.resolve, this.reject);
        }
        status = PENDING;
        resolve = () => {
            if (this.status !== PENDING) return;
            this.status = FULFILLED;
        };
        reject = () => {
            if (this.status !== PENDING) return;
            this.status = REJECTED;
        };
    }
    
    1. 既然每一个 Promise 对象都可以调用 then 方法,它应该是存在于原型对象上的
    const PENDING = 'pending';
    const FULFILLED = 'fulfilled';
    const REJECTED = 'reiected';
    
    class myPromise {
        constructor(executor) {
            executor(this.resolve, this.reject);
        }
        status = PENDING;
        resolve = () => {
            if (this.status !== PENDING) return;
            this.status = FULFILLED;
        };
        reject = () => {
            if (this.status !== PENDING) return;
            this.status = REJECTED;
        };
        // 定义 then 方法用来判断状态
        then (successCallback, failCallback) => {
            if (this.status === FULFILLED) {
                successCallback();
            } else if (this.status === REJECTED) {
                failCallback();
            }
        };
    }
    
    1. 当调用成功回调的时候应该传递成功的值,当调用失败回调的时候应该传递失败的原因
    const PENDING = 'pending';
    const FULFILLED = 'fulfilled';
    const REJECTED = 'reiected';
    
    class myPromise {
        constructor(executor) {
            executor(this.resolve, this.reject);
        }
        status = PENDING;
        
        // 成功和失败,默认情况下是没有的,所以值应该是 undefined
        value = undefined;
        reason = undefined;
        
        // 接收成功的值
        resolve = value => {
            if (this.status !== PENDING) return;
            this.status = FULFILLED;
            
            // 保存成功之后的值
            this.value = value;
        };
        
        // 接收失败的原因
        reject = reason => {
            if (this.status !== PENDING) return;
            this.status = REJECTED;
            
            // 保存失败之后的原因
            this.reason = reason;
        };
        then (successCallback, failCallback) => {
            if (this.status === FULFILLED) {
                successCallback(this.value);
            } else if (this.status === REJECTED) {
                failCallback(this.reason);
            }
        };
    }
    
    1. 到此为止一个极其简化版的 Promise 就酱婶儿完成了。

    接下来实现的是 Promise 关于异步的部分


    起源地下载网 » Promise 系列(1)-- 核心逻辑实现

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元