美文网首页
59.JS->手写Promise

59.JS->手写Promise

作者: wo不是黄蓉 | 来源:发表于2022-02-20 18:36 被阅读0次

    day11:跟着训练营第一个手写promise
    注意点:
    1.new Promise参数里面的回调函数必传->首先定义基本结构

    calss MyPromise{
      constructor(fn){
        //1.判断传参是否是一个函数
        if (Object.prototype.toString.call(fn) != "[object Function]")
          throw new Error("Promise resolver undefined is not a function");
      }
    }
    let p = new MyPromise((resolve,reject)=>{})
    

    2.执行resolve

    calss MyPromise{
      constructor(fn){
        //1.判断传参是否是一个函数
        if (Object.prototype.toString.call(fn) != "[object Function]")
          throw new Error("Promise resolver undefined is not a function");
        //2.回调函数传入的参数问题
        //执行fn,将this绑定到resolve上->使用call,apply,bind方法
        fn(this.resolve.bind(this), this.reject.bind(this));
      }
      //定义resolve,和reject,在此可以接受到resolve和reject的值
      resolve(value) {
        console.log(value)
      }
      reject(errValue){}
    }
    let p = new MyPromise((resolve,reject)=>{
      resolve("resolve的值");
    })
    

    3.执行then中回调,then执行的回调函数的参数是resolve的结果,状态一旦改变不可回溯,then中的回调是异步代码

    //定义状态信息
    const STATE = {
      PENDGING: "pending",
      FULFILLED: "fulfilled",
      REJECTED: "rejected",
    };
    calss MyPromise{
    //初始化状态
      PromiseState = "pending";
    //初始化结果值
      PromiseResult = undefined;
    //then回调函数
      thenCallback = undefined;
    //catch回调函数
      errCallback = undefined;
      constructor(fn){
        //1.判断传参是否是一个函数
        if (Object.prototype.toString.call(fn) != "[object Function]")
          throw new Error("Promise resolver undefined is not a function");
        //2.回调函数传入的参数问题
        //执行fn,将this绑定到resolve上->使用call,apply,bind方法
        fn(this.resolve.bind(this), this.reject.bind(this));
      }
      //3.定义resolve,和reject,在此可以接受到resolve和reject的值
      resolve(value) {
        console.log(value)
        if (this.PromiseState === STATE.PENDGING) {
          this.PromiseState = STATE.FULFILLED;
          this.PromiseResult = value;
            //then中执行内容分为异步内容,借助settimtout的回调函数实现,在then回调中给thenCallback进行赋值,resolve执行后如果有then则执行
            setTimeout(() => {
              if (this.thenCallback) {
                this.thenCallback(value);
              }
            });
        }
      }
      reject(errValue){}
    }
    MyPromise.prototype.then = function (callback) {
      this.thenCallback = callback;
    }
    let p = new MyPromise((resolve,reject)=>{
      resolve("resolve的值");
    })
    p.then((res)=>{
        console.log(res);//resolve的值
         console.log("第一个then执行");//第一个then执行
    })
    

    4.实现then的链式调用,上一次then中return的值为下一个then回调函数的参数

    //定义状态信息
    const STATE = {
      PENDGING: "pending",
      FULFILLED: "fulfilled",
      REJECTED: "rejected",
    };
    calss MyPromise{
    //初始化状态
      PromiseState = "pending";
    //初始化结果值
      PromiseResult = undefined;
    //then回调函数
      thenCallback = undefined;
    //catch回调函数
      errCallback = undefined;
      constructor(fn){
        //1.判断传参是否是一个函数
        if (Object.prototype.toString.call(fn) != "[object Function]")
          throw new Error("Promise resolver undefined is not a function");
        //2.回调函数传入的参数问题
        //执行fn,将this绑定到resolve上->使用call,apply,bind方法
        fn(this.resolve.bind(this), this.reject.bind(this));
      }
      //定义resolve,和reject,在此可以接受到resolve和reject的值
      resolve(value) {
        console.log(value)
        if (this.PromiseState === STATE.PENDGING) {
          this.PromiseState = STATE.FULFILLED;
          this.PromiseResult = value;
          if (value instanceof MyPromise) {
            //resolve的结果是一个promise的情况和不同值的情况
            value.then((res) => {
              if (this.thenCallback) {
                this.thenCallback(res);
              }
            });
          } else {
            //then中执行内容分为异步内容,借助settimtout的回调函数实现,在then回调中给thenCallback进行赋值,resolve执行后如果有then则执行
            setTimeout(() => {
              if (this.thenCallback) {
                this.thenCallback(value);
              }
            });
          }
        }
      }
        reject(errValue) {
        if (this.PromiseState === STATE.PENDGING) {
          this.PromiseState = STATE.REJECTED;
          this.PromiseResult = errValue;
          setTimeout(() => {
            //判断 错误回调函数是否已经注册
            if (this.errCallback) {
              this.errCallback(errValue);
            } else if (this.thenCallback) {
              this.thenCallback(errValue);
            } else {
              throw "this Promise was reject,but cannout font catch";
            }
          });
        }
      }
    }
    //then、catch、finally方法挂载到promise原型上的
    MyPromise.prototype.then = function (callback) {
      //执行callback并将resolve的值返回到then中
      // callback();
      //在then中给thencallback赋值
      // this.thenCallback = callback;
      //then返回一个新的promise来实现链式调用
      return new MyPromise((resolve, reject) => {
        this.thenCallback = function (value) {
          if (this.PromiseState == STATE.REJECTED) {
            reject(value);
          } else {
            //执行callback
            var callbackRes = callback(value);
            if (callbackRes instanceof MyPromise) {
              if (callbackRes.PromiseState == STATE.REJECTED) {
                callbackRes.catch(function (errValue) {
                  reject(errValue);
                });
              } else {
                //将callback的值作为下一次的函数的传参
                resolve(callbackRes);
              }
            }
          }
        };
      });
    };
    
    let p = new MyPromise((resolve,reject)=>{
      resolve("resolve的值");
    })
    p.then((res)=>{
        console.log(res);//resolve的值
         console.log("第一个then执行");//第一个then执行
        return "第一个then return的值"
    }).then((res)=>{
        console.log(res);//第一个then return的值
         console.log("第二个then执行");//第二个then执行
    })
    

    5.实现catch
    和then实现流程类似,catch触发之后流程结束。需要注意的是:当then后链式调用catch时,此时状态已经变为了rejected,无法注册catch,因此无法给errCallback赋值。此时需要判断promise在reject时如果没有errCallback就去检测是否存在thenCallback,直到找到到errCallback注册完成,接下来调用errCallback。

      reject(errValue) {
        if (this.PromiseState === STATE.PENDGING) {
          this.PromiseState = STATE.REJECTED;
          this.PromiseResult = errValue;
          setTimeout(() => {
            //判断 错误回调函数是否已经注册
            if (this.errCallback) {
              this.errCallback(errValue);
            } else if (this.thenCallback) {
              this.thenCallback(errValue);
            } else {
              throw "this Promise was reject,but cannout font catch";
            }
          });
        }
      }
    MyPromise.prototype.catch = function (callback) {
      this.errCallback = callback;
      return new MyPromise(function (resolve, reject) {
        this.errCallback = function (errValue) {
          if (this.PromiseState == STATE.REJECTED) {
            reject(value);
          } else {
            var callbackRes = callback(errValue);
            resolve(callbackRes);
          }
        };
      });
    };
    
    let p = new MyPromise((resolve,reject)=>{
      reject("reject的值");
    })
    p.then((res)=>{
        console.log(res);//resolve的值
         console.log("第一个then执行");//第一个then执行
        return "第一个then return的值"
    }).then((res)=>{
        console.log(res);//第一个then return的值
         console.log("第二个then执行");//第二个then执行
    }).catch((err)=>{
      console.log(err)//reject的值
    })
    

    6.实现promise.all

    //promise-all
    MyPromise.all = function (arr) {
      let resultArr = [];
      //记录状态
      let rejectState = false;
      //错误值
      let errValue = undefined;
      //里面传的是3个promise,分别执行,有一个出错抛出异常
      return new MyPromise((resolve, reject) => {
        for (let i = 0; i < arr.length; i++) {
          //执行arr[i]
          (function (i) {
            let tempThen = arr[i];
            tempThen
              .then((res) => {
                //保存执行结果
                resultArr[i] = res;
                //判断是否有出错的元素
                let filterPromise = arr.every((item) => {
                  return item.PromiseState === STATE.FULFILLED;
                });
                if (filterPromise) {
                  resolve(resultArr);
                }
              })
              .catch((err) => {
                //错误值-状态改变
                rejectState = true;
                errValue = err;
                reject(err);
              });
          })(i);
          if (rejectState) {
            break;
          }
        }
      });
    };
    
    let p1 = new MyPromise(function (resolve, reject) {
      resolve("resolve的值");
      // reject("reject的值");
    });
    
    let promise1 = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        resolve("第一个异步任务执行");
      }, 3000);
    });
    let promise2 = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        // resolve("第二个异步任务执行");
        reject("第二个异步任务执行-失败");
      }, 2000);
    });
    let promise3 = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        resolve("第三个异步任务执行");
      }, 1000);
    });
    //调用resolve时,返回一个数组,表示三个执行结果。调用reject时,返回最快返回的一个执行结果
    MyPromise.all([promise1, promise2, promise3])
      .then((res) => {
        console.log(res);
      })
      .catch((err) => {
        console.log(err);//第二个异步任务执行-失败
      });
    

    7.实现promise.race

    //promise-race,返回最快的那一个。无论执行结果是正确还是错误
    MyPromise.race = function (promiseArr) {
    //状态标识
      let end = false;
      return new MyPromise((resolve, reject) => {
        (function (i) {
          for (let i = 0; i < promiseArr.length; i++) {
            promiseArr[i]
              .then((res) => {
                end = true;
                resolve(res);
              })
              .catch((err) => {
                end = true;
                reject(err);
              });
          }
        })();
      });
    };
    MyPromise.race([promise1, promise2, promise3])
      .then((res) => {
        console.log(res);//第三个异步任务执行
      })
      .catch((err) => {
        console.log(err);
      });
    

    最终版:

    //3.定义promise三个状态
    const STATE = {
      PENDGING: "pending",
      FULFILLED: "fulfilled",
      REJECTED: "rejected",
    };
    
    class MyPromise {
      PromiseState = "pending";
      PromiseResult = undefined;
      thenCallback = undefined;
      errCallback = undefined;
      constructor(fn) {
        this.PromiseState = STATE.PENDGING;
        //1.判断传参是否是一个函数
        if (Object.prototype.toString.call(fn) != "[object Function]")
          throw new Error("Promise resolver undefined is not a function");
    
        //2.回调函数传入的参数问题吗
        //执行fn,将this绑定到resolve上
        fn(this.resolve.bind(this), this.reject.bind(this));
      }
    
      resolve(value) {
        if (this.PromiseState === STATE.PENDGING) {
          this.PromiseState = STATE.FULFILLED;
          this.PromiseResult = value;
          if (value instanceof MyPromise) {
            //resolve的结果是一个promise的情况
            value.then((res) => {
              if (this.thenCallback) {
                this.thenCallback(res);
              }
            });
          } else {
            //then中执行内容分为异步内容,借助settimtout的回调函数实现,在then回调中给thenCallback进行赋值,resolve执行后如果有then则执行
            setTimeout(() => {
              if (this.thenCallback) {
                this.thenCallback(value);
              }
            });
          }
        }
        // console.log(value, this.PromiseState);
      }
      reject(errValue) {
        if (this.PromiseState === STATE.PENDGING) {
          this.PromiseState = STATE.REJECTED;
          this.PromiseResult = errValue;
          setTimeout(() => {
            //判断 错误回调函数是否已经注册
            if (this.errCallback) {
              this.errCallback(errValue);
            } else if (this.thenCallback) {
              this.thenCallback(errValue);
            } else {
              throw "this Promise was reject,but cannot font catch";
            }
          });
        }
      }
    }
    
    //then、catch、finally方法挂载到promise原型上的
    MyPromise.prototype.then = function (callback) {
      //执行callback并将resolve的值返回到then中
      // callback();
      //在then中给thencallback赋值
      // this.thenCallback = callback;
      //then返回一个新的promise来实现链式调用
      return new MyPromise((resolve, reject) => {
        this.thenCallback = function (value) {
          if (this.PromiseState == STATE.REJECTED) {
            reject(value);
          } else {
            //执行callback
            var callbackRes = callback(value);
            if (callbackRes instanceof MyPromise) {
              if (callbackRes.PromiseState == STATE.REJECTED) {
                callbackRes.catch(function (errValue) {
                  reject(errValue);
                });
              } else {
                //将callback的值作为下一次的函数的传参
                resolve(callbackRes);
              }
            }
          }
        };
      });
    };
    MyPromise.prototype.catch = function (callback) {
      this.errCallback = callback;
      return new MyPromise(function (resolve, reject) {
        this.errCallback = function (errValue) {
          if (this.PromiseState == STATE.REJECTED) {
            reject(value);
          } else {
            var callbackRes = callback(errValue);
            resolve(callbackRes);
          }
        };
      });
    };
    
    //promise-all
    MyPromise.all = function (arr) {
      let resultArr = [];
      //记录状态
      let rejectState = false;
      //错误值
      let errValue = undefined;
      //里面传的是3个promise,分别执行,有一个出错抛出异常
      return new MyPromise((resolve, reject) => {
        for (let i = 0; i < arr.length; i++) {
          //执行arr[i]
          (function (i) {
            let tempThen = arr[i];
            tempThen
              .then((res) => {
                //保存执行结果
                resultArr[i] = res;
                //判断是否有出错的元素
                let filterPromise = arr.every((item) => {
                  return item.PromiseState === STATE.FULFILLED;
                });
                if (filterPromise) {
                  resolve(resultArr);
                }
              })
              .catch((err) => {
                //错误值-状态改变
                rejectState = true;
                errValue = err;
                reject(err);
              });
          })(i);
          if (rejectState) {
            break;
          }
        }
      });
    };
    
    //promise-race,返回最快的那一个或者遇到的第一个错误
    MyPromise.race = function (promiseArr) {
      let end = false;
      return new MyPromise((resolve, reject) => {
        (function (i) {
          for (let i = 0; i < promiseArr.length; i++) {
            promiseArr[i]
              .then((res) => {
                end = true;
                resolve(res);
              })
              .catch((err) => {
                end = true;
                reject(err);
              });
          }
        })();
      });
    };
    let p1 = new MyPromise(function (resolve, reject) {
      resolve("resolve的值");
      // reject("reject的值");
    });
    
    let promise1 = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        resolve("第一个异步任务执行");
      }, 3000);
    });
    let promise2 = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        // resolve("第二个异步任务执行");
        reject("第二个异步任务执行-失败");
      }, 2000);
    });
    let promise3 = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        resolve("第三个异步任务执行");
      }, 1000);
    });
    MyPromise.all([promise1, promise2, promise3])
      .then((res) => {
        console.log(res);
      })
      .catch((err) => {
        console.log(err);
      });
    MyPromise.race([promise1, promise2, promise3])
      .then((res) => {
        console.log(res);
      })
      .catch((err) => {
        console.log(err);
      });
    // let p1then = p1
    //   .then((res) => {
    //     console.log(res);
    //     console.log("第一个then执行");
    //     return 123;
    //   })
    //   .then((res) => {
    //     console.log(res);
    //     console.log("第二个then执行");
    //     return MyPromise.reject("中断了");
    //   })
    //   .then((res) => {
    //     console.log(res);
    //     console.log("第三个then执行");
    //   })
    //   .catch((err) => {
    //     console.log(err);
    //   });
    

    相关文章

      网友评论

          本文标题:59.JS->手写Promise

          本文链接:https://www.haomeiwen.com/subject/rkjvlrtx.html