8.手写Promise

115 阅读7分钟

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);
//   });