# 手写代码

# Promise

一个异步的解决方案,状态一旦确定就不能更改

三个状态:pending,fulfilled,rejected

# 从用法入手 , 一个最简单的例子:

let p = new Promise((resolve, reject) => {
  resolve(1);
});
p.then((value) => {
  console.log(1);
});

从上可得出,Promise是一个构造函数,传入一个函数作为参数,之后会同步的去执行这个函数,同时传入两个函数参数resolvereject,这里我们使用ES6Class来处理:

class Promise {
  // 唯一状态
  status = "pending";
  // 成功后存储的值
  resolveData = "";
  // 失败后的错误数据
  rejectData = "";

  constructor(func) {
    this.resolve = function (value) {
      this.status = "fulfilled";
      this.resolveData = value;
    };
    this.reject = function (error) {
      this.status = "rejected";
      this.rejectData = error;
    };

    func(this.resolve, this.reject);
  }
}

我们定义好构造函数后,获取到了成功后的数据,需要添加then方法:

class Promise {
  // ...
  then(resolveThen, rejectThen) {
    // 区分不同的状态
    if (this.status === "fulfilled") {
      resolveThen(this.resolveData);
    }

    if (this.status === "rejected") {
      rejectThen(this.rejectData);
    }
  }
}

# 传递数据

由于promise对象可以不停的去传递返回值,所以需要处理返回的数据,实现链式调用

let p = new Promise((resolve, reject) => {
  resolve(1);
});
p.then((value) => {
  return value;
}).then((value) => {
  console.log(value);
});
class Promise {
  // ...
  then(resolveThen, rejectThen) {
    return new Promise((resolve, reject) => {
      let result;
      // 区分不同的状态
      if (this.status === "fulfilled") {
        result = resolveThen(this.resolveData);
        resolve(result);
      }

      if (this.status === "rejected") {
        result = rejectThen(this.rejectData);
        reject(result);
      }
    });
  }
}

# 异步

最常见的异步操作,我们需要在then中单独处理逻辑

let p = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1);
  }, 5);
});
p.then((value) => {
  return value;
}).then((value) => {
  console.log(value);
});
class Promise {
  // ...
  // 处理异步的情况
  resolveCbs = [];
  rejectCbs = [];
  constructor(func) {
    this.resolve = function (value) {
      this.status = "fulfilled";
      this.resolveData = value;
      this.resolveCbs.forEach((cb) => cb());
    };
    this.reject = function (error) {
      this.status = "rejected";
      this.rejectData = error;
      this.rejectCbs.forEach((cb) => cb());
    };

    func(this.resolve, this.reject);
  }
  then(resolveThen, rejectThen) {
    return new Promise((resolve, reject) => {
      let result;
      // 区分不同的状态
      if (this.status === "fulfilled") {
        result = resolveThen(this.resolveData);
        resolve(result);
      }

      if (this.status === "rejected") {
        result = rejectThen(this.rejectData);
        reject(result);
      }

      // 异步
      if (this.status === "pending") {
        resolveThen &&
          this.resolveCbs.push(() => {
            result = resolveThen(this.resolveData);
            if (isPromise(result)) {
              // 外部如果有异步,可以通过宏任务队列排队执行
              setTimeout(() => {
                // 为了能够异步获取到result的值
                resolve(result.resolveValue);
              }, 5);
            } else {
              resolve(result);
            }
          });
        rejectThen &&
          this.rejectCbs.push(() => {
            result = rejectThen(this.rejectData);
            if (isPromise(result)) {
              // 外部如果有异步,可以通过宏任务队列排队执行
              setTimeout(() => {
                reject(result.rejectValue);
              }, 5);
            } else {
              reject(result);
            }
          });
      }
    });
  }
}