# 手写 简易promise

57 阅读4分钟

手写 promise

简易版实现基础功能 resolverejectthen

class MyPromise {
  constructor(executor) {
    // 接收一个作为函数类型的参数,并执行
    executor(this.resolve, this.reject);
  }
  // 结果值
  PromiseResult;
  // 默认状态
  PromiseState = "pending";

  // resolve 方法,用于将 Promise 状态设置为 fulfilled
  // 如果PromiseState不是默认值那么直接返回,避免多次赋值
  // 设置 Promise 结果值为传入的 value
  resolve = (value) => {
    if (this.PromiseState !== "pending") return;
    this.PromiseState = "fulfilled";
    this.PromiseResult = value;
  };
  
  // reject 方法,用于将 Promise 状态设置为 rejected
  reject = (value) => {
    if (this.PromiseState !== "pending") return;
    this.PromiseState = "rejected";
    this.PromiseResult = value;
  };
  
  // then 方法,Promise的回调函数
  // 根据PromiseResult的值来判断执行哪一个回调函数
  then = (onFulfilled, onRejected) => {
    if (this.PromiseState === "fulfilled") {
      onFulfilled(this.PromiseResult);
    } else if (this.PromiseState === "rejected") {
      onRejected(this.PromiseResult);
    }
  };
}

支持异步

then 调用时假如 promise 状态还是 pending 时,将两个回调函数存起来,当异步执行完,改变了状态,循环执行成功回调函数列表中的函数

class MyPromise {
  constructor(executor) {
    executor(this.resolve, this.reject);
  }
  // 成功回调函数
  FulfilledCallback = [];
  // 失败回调函数
  RejecteddCallback = [];
  PromiseState = "pending";
  PromiseResult;

  // 当异步执行完,改变了状态,循环执行成功回调函数列表中的函数,并将结果值传递
  resolve = (value) => {
    if (this.PromiseState !== "pending") return;
    this.PromiseState = "fulfilled";
    this.PromiseResult = value;
    while (this.FulfilledCallback.length) {
      this.FulfilledCallback.shift()(this.value);
    }
  };

  reject = (value) => {
    if (this.PromiseState !== "pending") return;
    this.PromiseState = "rejected";
    this.PromiseResult = value;
    while (this.RejecteddCallback.length) {
      this.RejecteddCallback.shift()(this.value);
    }
  };

  then = (onFulfilled, onRejected) => {
    if (this.PromiseState === "fulfilled") {
      onFulfilled(this.PromiseResult);
    } else if (this.PromiseState === "rejected") {
      onRejected(this.PromiseResult);
    } else if (this.PromiseState === "pending") {
      // then调用时,状态为pending 则将函数函数存起来
      this.FulfilledCallback.push(onFulfilled);
      this.RejecteddCallback.push(onRejected);
    }
  };
}

链式调用

链式调用需要then()的返回值是Promise

class MyPromise {
    
  // 其余代码

  then = (onFulfilled, onRejected) => {
    // 返回一个Promise对象
    return new MyPromise((resolve, reject) => {
      // resolvePromise 在pending阶段调用,传进去回调函数
      // 在resolvePromise中执行回调函数,得到promiseObj
      // 判断得到promiseObj类型是否是promise
      //  如果是则通过promiseObj.then(resolve, reject)来改变then返回值MyPromise的状态
      //  如果不是则默认成功,直接调用then返回值MyPromise的resolve方法
      const resolvePromise = (callback) => {
        const promiseObj = callback(this.PromiseResult);
        if (promiseObj instanceof MyPromise) {
          // 简写 相当于 promiseObj.then(value=>resolve(value),value=>reject(value))
          promiseObj.then(resolve, reject);  
        } else {
          resolve(promiseObj);
        }
      };
      if (this.PromiseState === "fulfilled") {
        resolvePromise(onFulfilled);
      } else if (this.PromiseState === "rejected") {
        resolvePromise(onRejected);
      } else if (this.PromiseState === "pending") {
        // 封装一下onFulfilled,onRejected回调函数,修改返回值promise的状态
        this.FulfilledCallback.push(resolvePromise.bind(this, onFulfilled));
        this.RejecteddCallback.push(resolvePromise.bind(this, onRejected));
      }
    });
  };
}

all 方法
接受一个 promise 数组,非 promise 的当做成功 全部成功返回结果数组,有一个失败则返回失败结果

static all = (promises) => {
  return new MyPromise((resolve, reject) => {
    let result = [];
    let resultAdd = (res) => {
      result.push(res);
      if (result.length === promises.length) resolve(result);
    };
    promises.forEach((promise) => {
      if (promise instanceof MyPromise) {
        promise.then(res=>resultAdd(res),err=>reject(err));
      } else {
        resultAdd(promise);
      }
    });
  });
};

any 方法
接受一个 promise 数组 返回第一个成功结果,全部失败则报错

static any = (promises) => {0
  return new MyPromise((resolve, reject) => {
    promises.forEach((promise, index) => {
      promise.then(
        (value) => resolve(value),
        (err) => {
          if(index == promises.length-1) reject(new AggregateError("All promises were rejected"));
        }
      );
    });
  });
};

race 方法 接受一个 promise 数组,非 promise 的当做成功 返回最快得到的结果,不论成功或者失败

static race = (promises) => {
  return new MyPromise((resolve, reject) => {
    promises.forEach((promise) => {
      if(promise instanceof MyPromise){
        promise.then(res=>resolve(res),err=>reject(err))
      }else{
        resolve(promise)
      }
    });
  });
};

allSettled 方法 接受一个 promise 数组,非 promise 的当做成功 把 promise 结果以数组方式返回

static allSettled = (promises) => {
  return new MyPromise((resolve, reject) => {
    let result = [];
    let resultAdd = (status,res) => {
      result.push({status,res});
      if (result.length === promises.length) resolve(result);
    };
    promises.forEach((promise) => {
      if (promise instanceof MyPromise) {
        promise.then(res=>resultAdd('fulfilled',res),err=>resultAdd('rejected',err));
      } else {
        resultAdd('fulfilled',promise);
      }
    });
  });
};

Promise.resolve()

static resolve = (value) => {
  return new MyPromise((resolve) => resolve(value));
};

Promise.reject()

static reject = (value) => {
  return new MyPromise((resolve,reject) => reject(value));
};

catch 方法 接受一个回调函数 其实就是 then 方法第二参数,语法糖

catch = (callback)=>{
  return this.then(undefined,callback)
}

finally 方法 接受一个回调函数 无论结果是成功或者失败都会执行 finally 无法获取上一个 promise 传出来的值 .then(() => value 这个的话是为了 finally 后面调用 then 的话可以获取之前的 finally 获取的 value

finally = (callback)=>{
 return this.then(
    (value) => MyPromise.resolve(callback()).then(() => value),
    (reason) =>
      MyPromise.resolve(callback()).then(() => {
        throw reason;
      })
  );
}

完整代码

class MyPromise {
  constructor(executor) {
    executor(this.resolve, this.reject);
  }
  FulfilledCallback = [];
  RejecteddCallback = [];
  PromiseState = "pending";
  PromiseResult;

  resolve = (value) => {
    if (this.PromiseState !== "pending") return;
    this.PromiseState = "fulfilled";
    this.PromiseResult = value;
    while (this.FulfilledCallback.length) {
      this.FulfilledCallback.shift()(value);
    }
  };

  reject = (value) => {
    if (this.PromiseState !== "pending") return;
    this.PromiseState = "rejected";
    this.PromiseResult = value;
    while (this.RejecteddCallback.length) {
      this.RejecteddCallback.shift()(value);
    }
  };

  then = (onFulfilled, onRejected) => {
    // 判断毁掉函数是否为空
    onFulfilled =
      typeof onFulfilled === "function" ? onFulfilled : (val) => val;
    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (reason) => {
            throw reason;
          };

    return new MyPromise((resolve, reject) => {
      const resolvePromise = (callback) => {
        queueMicrotask(() => {
          const promiseObj = callback(this.PromiseResult);
          if (promiseObj instanceof MyPromise) {
            promiseObj.then(resolve, reject);
          } else {
            resolve(promiseObj);
          }
        });
      };
      if (this.PromiseState === "fulfilled") {
        resolvePromise(onFulfilled);
      } else if (this.PromiseState === "rejected") {
        resolvePromise(onRejected);
      } else if (this.PromiseState === "pending") {
        this.FulfilledCallback.push(resolvePromise.bind(this, onFulfilled));
        this.RejecteddCallback.push(resolvePromise.bind(this, onRejected));
      }
    });
  };

  catch = (callback) => {
    return this.then(undefined, callback);
  };

  finally = (callback) => {
    return this.then(
      (value) => MyPromise.resolve(callback()).then(() => value),
      (reason) =>
        MyPromise.resolve(callback()).then(() => {
          throw reason;
        })
    );
  };

  static all = (promises) => {
    return new MyPromise((resolve, reject) => {
      let result = [];
      let resultAdd = (res) => {
        result.push(res);
        if (result.length === promises.length) resolve(result);
      };
      promises.forEach((promise) => {
        if (promise instanceof MyPromise) {
          promise.then(
            (res) => resultAdd(res),
            (err) => reject(err)
          );
        } else {
          resultAdd(promise);
        }
      });
    });
  };

  static any = (promises) => {
    return new MyPromise((resolve, reject) => {
      promises.forEach((promise, index) => {
        promise.then(
          (value) => resolve(value),
          (err) => {
            if (index == promises.length - 1)
              reject(new AggregateError("All promises were rejected"));
          }
        );
      });
    });
  };

  static race = (promises) => {
    return new MyPromise((resolve, reject) => {
      promises.forEach((promise) => {
        if (promise instanceof MyPromise) {
          promise.then(
            (res) => resolve(res),
            (err) => reject(err)
          );
        } else {
          resolve(promise);
        }
      });
    });
  };

  static allSettled = (promises) => {
    return new MyPromise((resolve, reject) => {
      let result = [];
      let resultAdd = (status, res) => {
        result.push({ status, res });
        if (result.length === promises.length) resolve(result);
      };
      promises.forEach((promise) => {
        if (promise instanceof MyPromise) {
          promise.then(
            (res) => resultAdd("fulfilled", res),
            (err) => resultAdd("rejected", err)
          );
        } else {
          resultAdd("fulfilled", promise);
        }
      });
    });
  };

  static resolve = (value) => {
    return new MyPromise((resolve,reject) => resolve(value));
  };

  static reject = (value) => {
    return new MyPromise((resolve,reject) => reject(value));
  };
}