手写promise,包括类方法

    <script>
      // 定义三个常量表示promise的状态
      const PROMISE_STATUS_PENDING = "pending";
      const PROMISE_STATUS_FULFILLED = "fulfilled";
      const PROMISE_STATUS_REJECTED = "reject";
      // 封装工具函数
      function execFunctionWithCatchError(execFn, value, resovle, reject) {
        try {
          const result = execFn(value);
          resovle(result);
        } catch (err) {
          reject(err);
        }
      }
      class HYPromise {
        constructor(executor) {
          this.status = PROMISE_STATUS_PENDING;
          //   保存并传递值给then
          this.value = undefined;
          this.reason = undefined;
          this.onFulfilledFns = [];
          this.onRejectedFns = [];
          const resolve = (value) => {
            if (this.status === PROMISE_STATUS_PENDING) {
              queueMicrotask(() => {
                if (this.status !== PROMISE_STATUS_PENDING) return;
                this.status = PROMISE_STATUS_FULFILLED;
                this.value = value;
                this.onFulfilledFns.forEach((fn) => {
                  fn();
                });
                //   执行传入then的第一个回调函数
              });
            }
          };
          const reject = (reason) => {
            if (this.status === PROMISE_STATUS_PENDING) {
              queueMicrotask(() => {
                if (this.status !== PROMISE_STATUS_PENDING) return;
                this.status = PROMISE_STATUS_REJECTED;
                this.reason = reason;
                this.onRejectedFns.forEach((fn) => {
                  fn();
                });
                //   执行传入then的第二个回调函数
              });
            }
          };
          try {
            executor(resolve, reject);
          } catch (err) {
            reject(err);
          }
        }
        then(onFulfilled, onRejected) {
          // 利用抛错让下一个promise的catch帮忙处理
          onRejected =
            onRejected ||
            ((err) => {
              throw err;
            });
          // 防止catch方法让链式调用断层
          onFulfilled =
            onFulfilled ||
            ((value) => {
              return value;
            });
          return new HYPromise((resolve, reject) => {
            // 如果在then调用的时候,状态已经确定下来
            if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
              execFunctionWithCatchError(
                onFulfilled,
                this.value,
                resolve,
                reject
              );
            }
            if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
              execFunctionWithCatchError(
                onRejected,
                this.reason,
                resolve,
                reject
              );
            }
            // 将成功回调和失败回调放入对应的数组
            if (this.status === PROMISE_STATUS_PENDING) {
              if (onFulfilled) {
                this.onFulfilledFns.push(() => {
                  execFunctionWithCatchError(
                    onFulfilled,
                    this.value,
                    resolve,
                    reject
                  );
                });
              }
              if (onRejected) {
                this.onRejectedFns.push(() => {
                  execFunctionWithCatchError(
                    onRejected,
                    this.reason,
                    resolve,
                    reject
                  );
                });
              }
            }
          });
        }
        catch(onRejected) {
          return this.then(undefined, onRejected);
        }
        finally(onFinally) {
          this.then(
            () => {
              onFinally();
            },
            () => {
              onFinally();
            }
          );
        }
        // 类方法
        static resolve(value) {
          return new HYPromise((resolve, reject) => {
            resolve(value);
          });
        }
        static reject(reason) {
          return new HYPromise((resolve, reject) => {
            reject(reason);
          });
        }
        static all(promises) {
          // 关键在什么时候执行resolve,什么时候执行reject
          return new HYPromise((resolve, reject) => {
            const values = [];
            promises.forEach((promise) => {
              promise.then(
                (res) => {
                  values.push(res);
                  if (values.length === promises.length) {
                    resolve(values);
                  }
                },
                (err) => {
                  reject(err);
                }
              );
            });
          });
        }
        static allSettled(promises) {
          return new HYPromise((resolve) => {
            const results = [];
            promises.forEach((promise) => {
              promise.then(
                (res) => {
                  results.push({
                    status: PROMISE_STATUS_FULFILLED,
                    vaule: res,
                  });
                  if (results.length === promises.length) {
                    resolve(results);
                  }
                },
                (err) => {
                  results.push({
                    stauts: PROMISE_STATUS_REJECTED,
                    reason: err,
                  });
                  if (results.length === promises.length) {
                    resolve(results);
                  }
                }
              );
            });
          });
        }
        static race(promises) {
          return new HYPromise((resolve, reject) => {
            promises.forEach((promise) => {
              // promise.then((res) => {
              //   resolve(res),
              //     (err) => {
              //       resolve(err);
              //     };
              // });
              // 神来之笔的简化
              promise.then(resolve, reject);
            });
          });
        }
        static any(promises) {
          // resolve必须等到有一个成功的结果
          // reject所有的都失败才执行reject
          const reasons = [];
          return new HYPromise((resolve, reject) => {
            promises.forEach((promise) => {
              promise.then(resolve, (err) => {
                reasons.push(err);
                if (reasons.length === promises.length) {
                  reject(new AggregateError(reasons));
                }
              });
            });
          });
        }
      }

      // 实验
      const p1 = new HYPromise((resolve, reject) => {
        setTimeout(() => {
          reject("111");
        }, 1000);
      });
      const p2 = new HYPromise((resolve, reject) => {
        setTimeout(() => {
          reject("222");
        }, 2000);
      });
      const p3 = new HYPromise((resolve, reject) => {
        setTimeout(() => {
          reject("333");
        }, 3000);
      });

      HYPromise.any([p1, p2, p3])
        .then((res) => {
          console.log(res);
        })
        .catch((err) => {
          console.log(err);
        });
    </script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值