Skip to main content

Command Palette

Search for a command to run...

手写Promise

Updated
4 min readView as Markdown

手写Promise 构造函数

// 声明构造函数
function Promise(executor) {
  this.PromiseState = "pending";
  this.promiseResult = null;
  // 保存回调函数
  this.callbacks = [];
  // 保存实例对象的this的值(也可以用匿名箭头函数)
  let self = this;
  // resolve函数
  function res(data) {
    // 设置状态只能修改一次
    if (self.PromiseState !== "pending") return;
    // 1.修改对象的状态(promiseState)
    self.PromiseState = "fulfilled";
    // 2.修改对象结果值(promiseResult)
    self.promiseResult = data;
    // 调用成功的回调函数(加定时器变为异步)
    setTimeout(() => {
      self.callbacks.forEach((item) => {
        item.onRes(data);
      });
    });
  }
  // reject函数
  const rej = (data) => {
    // 设置状态只能修改一次
    if (this.PromiseState !== "pending") return;
    // 1.修改对象的状态(promiseState)
    this.PromiseState = "rejected";
    // 2.修改对象结果值(promiseResult)
    this.promiseResult = data;
    // 调用失败的回调函数(加定时器变为异步)
    setTimeout(() => {
      this.callbacks.forEach((item) => {
        item.onRej(data);
      });
    });
  };

  // 捕获异常
  try {
    // 同步调用【执行器函数】
    executor(res, rej);
  } catch (error) {
    rej(error);
  }
}

// 添加then方法
Promise.prototype.then = function (onRes, onRej) {
  // 保存this
  let self = this;
  // 实现异常穿透 添加默认值
  if (typeof onRej !== "function") {
    onRej = (reason) => {
      throw reason;
    };
  }
  if (typeof onRes !== "function") {
    onRes = (value) => value;
  }
  return new Promise((res, rej) => {
    // 封装函数
    function callback(type) {
      try {
        // 保存回调函数的返回值
        let result = type(self.promiseResult);
        // 判断返还值是否为一个promise对象
        if (result instanceof Promise) {
          // promise对象 执行then方法
          result.then(
            (s) => {
              res(s);
            },
            (f) => {
              rej(f);
            }
          );
        } else {
          // 非promise对象
          res(result);
        }
      } catch (error) {
        rej(error);
      }
    }
    // 回调函数
    if (this.PromiseState === "fulfilled") {
      // 异步调用
      setTimeout(() => {
        callback(onRes);
      });
    }
    if (this.PromiseState === "rejected") {
      // 异步调用
      setTimeout(() => {
        callback(onRej);
      });
    }
    // 解决异步回调 多重调用
    // 判断pending状态
    if (this.PromiseState === "pending") {
      // 保存回调函数
      this.callbacks.push({
        onRes: function () {
          callback(onRes);
        },
        onRej: () => {
          callback(onRej);
        },
      });
    }
  });
};
// 添加catch方法
Promise.prototype.catch = function (onRej) {
  return this.then(undefined, onRej);
};
// 添加resolve方法
Promise.resolve = function (value) {
  // 返回promise对象
  return new Promise((res, rej) => {
    if (value instanceof Promise) {
      value.then(
        (v) => {
          res(v);
        },
        (s) => {
          rej(s);
        }
      );
    } else {
      // 将状态设置为成功
      res(value);
    }
  });
};
// 添加reject方法
Promise.reject = function (value) {
  // 返回promise对象
  return new Promise((res, rej) => {
    rej(value);
  });
};
// 添加all方法
Promise.all = function (promises) {
  return new Promise((res, rej) => {
    // 计数变量
    let count = 0;
    // 保存成功结果数组
    let resultArr = [];
    for (let i = 0; i < promises.length; i++) {
      promises[i].then(
        (v) => {
          // 成功时,count加一
          count++;
          // 不使用push,有可能是异步,顺序可能对不上
          resultArr[i] = v;
          // 当count等于promises的长度时,说明数组内每一个都成功
          if (count === promises.length) {
            res(resultArr);
          }
        },
        (j) => {
          rej(j);
        }
      );
    }
  });
};
// 添加race方法
Promise.race = function (promises) {
  return new Promise((res, rej) => {
    promises.forEach((item) => {
      item.then(
        (v) => {
          // 修改结果为成功
          res(v);
          return;
        },
        (j) => {
          // 修改结果为失败
          rej(j);
          return;
        }
      );
    });
  });
};

手写Promise 类

export default class Promise {
  constructor(executor) {
    this.PromiseState = "pending";
    this.promiseResult = null;
    // 保存回调函数
    this.callbacks = [];
    // 保存实例对象的this的值(也可以用匿名箭头函数)
    let self = this;
    // resolve函数
    function res(data) {
      // 设置状态只能修改一次
      if (self.PromiseState !== "pending") return;
      // 1.修改对象的状态(promiseState)
      self.PromiseState = "fulfilled";
      // 2.修改对象结果值(promiseResult)
      self.promiseResult = data;
      // 调用成功的回调函数(加定时器变为异步)
      setTimeout(() => {
        self.callbacks.forEach((item) => {
          item.onRes(data);
        });
      });
    }
    // reject函数
    const rej = (data) => {
      // 设置状态只能修改一次
      if (this.PromiseState !== "pending") return;
      // 1.修改对象的状态(promiseState)
      this.PromiseState = "rejected";
      // 2.修改对象结果值(promiseResult)
      this.promiseResult = data;
      // 调用失败的回调函数(加定时器变为异步)
      setTimeout(() => {
        this.callbacks.forEach((item) => {
          item.onRej(data);
        });
      });
    };

    // 捕获异常
    try {
      // 同步调用【执行器函数】
      executor(res, rej);
    } catch (error) {
      rej(error);
    }
  }

  // then方法
  then(onRes, onRej) {
    // 保存this
    let self = this;
    // 实现异常穿透 添加默认值
    if (typeof onRej !== "function") {
      onRej = (reason) => {
        throw reason;
      };
    }
    if (typeof onRes !== "function") {
      onRes = (value) => value;
    }
    return new Promise((res, rej) => {
      // 封装函数
      function callback(type) {
        try {
          // 保存回调函数的返回值
          let result = type(self.promiseResult);
          // 判断返还值是否为一个promise对象
          if (result instanceof Promise) {
            // promise对象 执行then方法
            result.then(
              (s) => {
                res(s);
              },
              (f) => {
                rej(f);
              }
            );
          } else {
            // 非promise对象
            res(result);
          }
        } catch (error) {
          rej(error);
        }
      }
      // 回调函数
      if (this.PromiseState === "fulfilled") {
        // 异步调用
        setTimeout(() => {
          callback(onRes);
        });
      }
      if (this.PromiseState === "rejected") {
        // 异步调用
        setTimeout(() => {
          callback(onRej);
        });
      }
      // 解决异步回调 多重调用
      // 判断pending状态
      if (this.PromiseState === "pending") {
        // 保存回调函数
        this.callbacks.push({
          onRes: function () {
            callback(onRes);
          },
          onRej: () => {
            callback(onRej);
          },
        });
      }
    });
  }

  // 添加catch方法
  catch(onRej) {
    return this.then(undefined, onRej);
  }

  // 添加resolve方法
  static resolve(value) {
    // 返回promise对象
    return new Promise((res, rej) => {
      if (value instanceof Promise) {
        value.then(
          (v) => {
            res(v);
          },
          (s) => {
            rej(s);
          }
        );
      } else {
        // 将状态设置为成功
        res(value);
      }
    });
  }

  // 添加reject方法
  static reject(value) {
    // 返回promise对象
    return new Promise((res, rej) => {
      rej(value);
    });
  }

  // 添加all方法
  static all(promises) {
    return new Promise((res, rej) => {
      // 计数变量
      let count = 0;
      // 保存成功结果数组
      let resultArr = [];
      for (let i = 0; i < promises.length; i++) {
        promises[i].then(
          (v) => {
            // 成功时,count加一
            count++;
            // 不使用push,有可能是异步,顺序可能对不上
            resultArr[i] = v;
            // 当count等于promises的长度时,说明数组内每一个都成功
            if (count === promises.length) {
              res(resultArr);
            }
          },
          (j) => {
            rej(j);
          }
        );
      }
    });
  }

  // 添加race方法
  static race(promises) {
    return new Promise((res, rej) => {
      promises.forEach((item) => {
        item.then(
          (v) => {
            // 修改结果为成功
            res(v);
            return;
          },
          (j) => {
            // 修改结果为失败
            rej(j);
            return;
          }
        );
      });
    });
  }
}

More from this blog

js 数组方法

一、增删改方法 push()方法接收任意数量的参数,并将它们添加到数组末尾,返回数组的最新长度 unshift()在数组开头添加任意多个值,然后返回新的数组长度 pop() 方法用于删除数组的最后一项,同时减少数组的 length 值,返回被删除的项 shift()方法用于删除数组的第一项,同时减少数组的 length 值,返回被删除的项 splice功能强大,可以同时对数组进行增删改的操作 二、搜索和位置方法 indexOf()返回要查找的元素在数组中第一次出现的下标,如果没找到则返回 -1 ...

Oct 16, 20231 min read

Server-Sent Events(SSE)

Server-Sent Events(SSE)是一种用于实现服务器向客户端实时推送数据的Web技术。与传统的轮询和长轮询相比,SSE提供了更高效和实时的数据推送机制。 SSE基于HTTP协议,允许服务器将数据以事件流(Event Stream)的形式发送给客户端。客户端通过建立持久的HTTP连接,并监听事件流,可以实时接收服务器推送的数据。 SSE的主要特点包括: 简单易用:SSE使用基于文本的数据格式,如纯文本、JSON等,使得数据的发送和解析都相对简单。 单向通信:SSE支持服务器向客户...

Sep 21, 20231 min read

Untitled Publication

28 posts