ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

自定义Promise

2021-12-27 22:02:16  阅读:198  来源: 互联网

标签:resolve 函数 自定义 对象 Promise reject onRejected


class Promise {   // 构造方法   constructor(executor) {     // resolve函数---里面还需要声明形参去接收实参
    // 给实例对象的身上添加属性,直接通过this强行复制的方式去添加,这里的this就指的是新创建(new出来的)的实例对象     this.PromiseState = "pending";     this.PromiseResult = null;     // 声明属性用来保存then方法中的回调函数     this.callBacks = [];
    // 解决下方this指向问题,可以在这里先把this的指向保存下来     const that = this;     // const _this = this;     // const self = this; //三种保存this值的常见写法     function resolve(data) {       // 判断Promise实例对象的状态(状态变为成功或者失败就不能再次改动)       if (that.PromiseState !== "pending") return;       // 1.修改对象的状态(PromiseState)       // 注意:这里的this指向的不是新new出来实例对象,而是指向全局的Window对象(所以要提前把this的值保存下来)       that.PromiseState = "fulfilled"; //或者为resolve(意思都一样)       // 2.修改对象结果值(PromiseResult)       that.PromiseResult = data;       // 调用成功的回调函数       that.callBacks.forEach((item) => {         setTimeout(() => {           //加定时器让回调函数变为异步操作           item.onResolved(data); //forEach不会遍历数组元素为empty(空)的数组,所以加不加判断条件都不会影响性能         });       });     }     // reject函数---里面还需要声明形参去接收实参     function reject(data) {       // 判断Promise实例对象的状态(状态变为成功或者失败就不能再次改动)       if (that.PromiseState !== "pending") return;       // 1.修改对象的状态(PromiseState)       that.PromiseState = "rejected";       // 2.修改对象结果值(PromiseResult)       that.PromiseResult = data;       // 调用失败的回调函数       that.callBacks.forEach((item) => {         setTimeout(() => {           item.onRejected(data);         });       });     }
    // 同步调用(执行器函数-executor)     try {       executor(resolve, reject);     } catch (error) {       // 修改Promise实例对象的状态为失败       reject(error);     }   }
  // then方法的封装   then(onResolved, onRejected) {     const that = this;
    // 判断回调函数参数是否传递的是一个函数,如果不是一个函数,就给他添加一个默认值---值为函数     if (typeof onResolved !== "function") {       onResolved = (value) => value; //value=>{return value} ES6     }
    if (typeof onRejected !== "function") {       onRejected = (reason) => {         throw reason;       };     }     return new Promise((resolve, reject) => {       // 封装函数       function callBack(type) {         try {           // 在这里还有传入实参,实参为Promise实例对象成功之后的结果值           // 获取成功函数的执行结果           let result = type(that.PromiseResult); //this指向有问题,在函数内部直接调用,指的是Window
          // 判断result是不是Promise的实例对象           if (result instanceof Promise) {             //  如果是Promise类型的对象             result.then(               (v) => {                 resolve(v);               },               (r) => {                 reject(r);               }             );           } else {             // 结果的对象状态为成功             resolve(result);           }         } catch (error) {           reject(error);         }       }
      // 调用回调函数并且加上判断条件(判断Promise实例对象身上的PromiseState属性)       // 这里的this指的是Promise实例对象(函数包裹第一层的时候里面的this指向的是实例对象,第二层指向的是Window,除非第二层写箭头函数,箭头函数没有自己的this,所以this指向的就是外部的定义时的this,就是Promise实例对象),标准说法为构造函数中的this,后期谁调用指谁       if (this.PromiseState === "fulfilled") {         setTimeout(() => {           //加定时器更改回调函数为异步执行           callBack(onResolved);         });       }
      if (this.PromiseState === "rejected") {         setTimeout(() => {           callBack(onRejected);         });       }
      // 判断pending状态       if (this.PromiseState === "pending") {         // 保存回调函数         this.callBacks.push({           // ES6简写           // onResolved, //相当于onResolved:onResolved           // onRejected, //相当于onRejected:onRejected
          onResolved: function () {             callBack(onResolved);           },           onRejected: function () {             callBack(onRejected);           },         });       }     });   }
  // catch方法的封装   catch(onRejected) {     return this.then(undefined, onRejected);   }
  // resolve方法的封装   static resolve(value) {     return new Promise((resolve, reject) => {       if (value instanceof Promise) {         value.then(           (v) => {             resolve(v);           },           (r) => {             reject(r);           }         );       } else {         resolve(value);       }     });   }
  // reject方法的封装   static reject(reason) {     return new Promise((resolve, reject) => {       reject(reason);     });   }
  // all方法的封装   static all(promises) {     // 声明一个变量,用来判断promises数组里的Promise对象状态十分都为成功     let count = 0;     // 声明一个变量,用来保存成功的结果,结果是一个数组     let arr = [];
    // 结果为Promise的对象     return new Promise((resolve, reject) => {       // 遍历---这里的变量i必须使用let声明,不然i会被全局污染       for (let i = 0; i < promises.length; i++) {         // parmises[i]是其中的一个Promise对象         promises[i].then(           (v) => {             // 得知对象的状态是成功的             // 如果每一个Promise对象的状态都是成功的,才能去执行resolve函数             count++;             // 将当前Promise对象的结果存入到数组中             // arr.push(v);这种方法保存结果有点bug,异步的时候会导致顺序跟数组里面传进来Promise对象顺序不一致             arr[i] = v;             // 判断:如果count的值等于promises数组的长度,就说明这个promises数组里的Promise数组状态都为成功             if (count === promises.length) {               // 修改状态               resolve(arr);             }           },           (r) => {             reject(r);           }         );       }     });   }
  // race方法的封装   static race(promises) {     return new Promise((resolve, reject) => {       for (let i = 0; i < promises.length; i++) {         promises[i].then(           (v) => {             // 修改返回对象的状态为成功             resolve(v);           },           (r) => {             // 修改返回对象的状态为失败             reject(r);           }         );       }     });   } }

标签:resolve,函数,自定义,对象,Promise,reject,onRejected
来源: https://www.cnblogs.com/renag/p/15738060.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有