手写promise(3)-- 实例方法 静态方法

news2024/9/23 21:28:06

目录

实例方法

catch

finally

静态方法

reslove

 reject

race 

all 

allSettled

any


实例方法

提供给promise实例的方法 包括catch 与finally

catch

Promise 实例的 catch() 方法用于注册一个在 promise 被拒绝时调用的函数。它会立即返回一个等效的 Promise 对象,这可以允许你链式调用其他 promise 的方法。此方法是 Promise.prototype.then(undefined, onRejected) 的一种简写形式。

1 内部调用then方法(此方法是 Promise.prototype.then(undefined, onRejected) 的一种简写形式。

2.处理异常 因为是实例化生成前抛出的异常 要 catch 捕获实例化生成函数执行前

   constructor(func) {
    const resolve = (result) => {
      if (this.state == PENDING) {
        this.state = FULFILLED;
        this.result = result;
        this.#handlers.forEach(({ onFulfilled }) => {
          onFulfilled(this.result);
        });
      }
    };

    const reject = (result) => {
      if (this.state == PENDING) {
        this.state = REJECTED;
        this.result = result;
        this.#handlers.forEach(({ onRejected }) => {
          onRejected(this.result);
        });
      }
    };

    try {
      func(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }
 catch(onRejected) {
    return this.then(undefined, onRejected);
  }
// 测试代码

const p = new MyPromise((resolve, reject) => {
  reject("error");
  // throw "error";
  // return p2;
  // return 2;
  // return new MyPromise((resolve, reject) => {
  //   resolve("OK");
  //   // reject("ERROR");
  // });
});
p.then((res) => {
  console.log("res:", res);
}).catch((error) => {
  console.log("err:", err);
});

finally

Promise 实例的 finally() 方法用于注册一个在 promise 敲定(兑现或拒绝)时调用的函数。它会立即返回一个等效的 Promise 对象,这可以允许你链式调用其他 promise 方法。

finally() 方法类似于调用 then(onFinally, onFinally)

这可以让你避免在 promise 的 then() 和 catch() 处理器中重复编写代码。

  • onFinally 回调函数不接收任何参数。这种情况恰好适用于你不关心拒绝原因或兑现值的情况,因此无需提供它。
  • 如果你想在 promise 敲定时进行一些处理或者清理,无论其结果如何,那么 finally() 方法会很有用。
  finally(onFinally) {
    return this.then(onFinally, onFinally);
  }
const p = new MyPromise((resolve, reject) => {
  reject("error");
  // throw "error";
});
p.then((res) => {
  console.log("res:", res);
})
  .catch((error) => {
    console.log("err:", error);
  })
  .finally(() => {
    console.log("一定执行");
  });

静态方法

提供给promise静态的方法 包括以下6个

  • reslove
  • reject
  • race
  • all
  • allsettled
  • any

reslove

Promise.resolve() 静态方法将给定的值转换为一个 Promise。如果该值本身就是一个 Promise,那么该 Promise 将被返回;如果该值是一个 thenable 对象,Promise.resolve() 将调用其 then() 方法及其两个回调函数;否则,返回的 Promise 将会以该值兑现

  • 判断传入值
  • promise直接返回
  • 转为promise并返回  fulfilled状态

thenable对象指的是具有then方法的对象。Promise.resolve方法会将这个对象转为Promise对象,然后立即执行thenable对象的then方法

 /**
   * 静态方法 resolve
   *  判断传入值
   *    promise直接返回
   *    转为promise并返回  fulfilled状态
   */
  static resolve(value) {
    if (value instanceof MyPromise) {
      return value;
    }
    return new MyPromise((resolve, reject) => {
      resolve(value);
    });
  }

// 测试代码

// const p = MyPromise.resolve(
//   new MyPromise((resolve, reject) => {
//     resolve("ok");
//     // reject("error");
//     // throw "error";
//   })
// );
const p = MyPromise.resolve("贾公子");
p.then(
  (res) => {
    console.log("res:", res);
  },
  (error) => {
    console.log("err:", error);
  }
);

 reject

Promise.reject() 静态方法返回一个已拒绝(rejected)的 Promise 对象,拒绝原因为给定的参数。 

 static reject(value) {
    return new MyPromise((resolve, reject) => {
      reject(value);
    });
  }
// 测试代码
const p = MyPromise.reject("贾公子");
p.then(
  (res) => {
    console.log("res:", res);
  },
  (error) => {
    console.log("err:", error);
  }
);

race 

Promise.race() 静态方法接受一个 promise 可迭代对象作为输入,并返回一个 promise 这个返回的 promise 会随着第一个 promise 的敲定而敲定。

接收一个promise数组 返回的结果以第一个和promise返回的结果为准

* 返回promise

* 判断是否为数组(Array.isArray) 错误信息  Argument is not iterable

 * 等待第一个敲定 (forEach取出每一个promise执行 一旦执行就改变状态resolve包装一层 因为有可能传递的不是promise)

  /**
   * 静态方法 race
   * 返回promise
   * 判断是否为数组 错误信息  Argument is not iterable
   * 等待第一个敲定
   */
  static race(promises) {
    // 1.返回promise
    return new Promise((resolve, reject) => {
      // 2.判断是否为数组 错误信息  Argument is not iterable
      if (!Array.isArray(promises)) {
        return reject(new TypeError("Argument is not iterable"));
      }
      // 3.等待第一个敲定
      promises.forEach((p) => {
        MyPromise.resolve(p).then(
          (res) => resolve(res),
          (err) => reject(err)
        );
      });
    });
  }
}

// 测试代码

const p1 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve("ok");
  }, 2000);
});
const p2 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    reject("err");
  }, 1000);
});
const p = MyPromise.race([p1, p2]);
// const p = MyPromise.race();
p.then(
  (res) => {
    console.log("res:", res);
  },
  (error) => {
    console.log("err:", error);
  }
);

all 

 Promise.all() 静态方法接受一个 Promise 可迭代对象作为输入,并返回一个 Promise 。当所有输入的 Promise 都被兑现时,返回的 Promise 也将被兑现(即使传入的是一个空的可迭代对象),并返回一个包含所有兑现值的数组。如果输入的任何 Promise 被拒绝,则返回的 Promise 将被拒绝,并带有第一个被拒绝的原因。

  • 1.返回promise
  • 2.判断是否为数组 错误信息  Argument is not iterable
  • 3.空数组直接兑现
  • 4.判断全部兑现
  • 4.1记录结果(索引记录保证兑现顺序与传入顺序一样)
  • 4.2判断 全部兑现 (不能使用length 因为使用索引添加的可能导致没有全部兑现)
  • 5.处理第一个拒绝

  static all(promises) {
    // 1.返回promise
    return new Promise((resolve, reject) => {
      // 2.判断是否为数组 错误信息  Argument is not iterable
      if (!Array.isArray(promises)) {
        return reject(new TypeError("Argument is not iterable"));
      }

      // 3.空数组直接兑现
      promises.length === 0 && resolve(promises);
      // 4.判断全部兑现
      const result = [];
      let count = 0;
      promises.forEach((p, index) => {
        MyPromise.resolve(p).then(
          (res) => {
            // 4.1记录结果(索引记录保证兑现顺序与传入顺序一样)
            result[index] = res;
            // 4.2判断 全部兑现 (不能使用length 因为使用索引添加的可能导致没有全部兑现)
            count++;
            count === promises.length && resolve(result);
          },
          (err) => {
            // 5.处理第一个拒绝
            reject(err);
          }
        );
      });
    });
  }

// 测试代码
const p1 = MyPromise.resolve(1);
const p2 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    // resolve("ok");
    reject("err");
  }, 1000);
});
const p3 = "贾公子";
const p = MyPromise.all([p1, p2, p3]);
// const p = MyPromise.all();、
// const p = MyPromise.all([]);

p.then(
  (res) => {
    console.log("res:", res);
  },
  (error) => {
    console.log("err:", error);
  }
);

allSettled

Promise.allSettled() 静态方法将一个 Promise 可迭代对象作为输入,并返回一个单独的 promise。当所有输入的 Promise 都已敲定时(包括传入空的可迭代对象时),返回的 Promise 将被兑现,并带有描述每个 Promise 结果的对象数组。

  * 1.传入的promise都已敲定,即可获取兑现结果

 *  2.结果数组: [{status: 'fulfilled', value: 1},{status: 'rejected', reason: 'err'}]

 *  3.结果数组的顺序,和传入的promise数组的顺序是一样的

 *  4.空数组直接兑现

 *  5.不为数组 错误信息  Argument is not iterable

  • 1.返回promise  可以让结果继续.then
  •  2.数组判断 不为数组直接抛出异常
  • 3.为空直接敲定  判断length
  • 4.等待全部敲定 使用forech 循环处理 利用resolve包装一下
  • 4.1记录结果(result) 记录敲定的次数(count) 不使用push 会导致没有全部兑现
  • 4.2 处理兑现{ status: FULFILLED, value: res }
  • 4.3处理拒绝{ status: REJECTED, reason: err })
  • 成功或者失败都是resolve
  static allSettled(promises) {
    // 1.返回promise
    return new Promise((resolve, reject) => {
      // 2.数组判断
      if (!Array.isArray(promises)) {
        return reject(new TypeError("Argument is not iterable"));
      }
      // 3.为空直接敲定
      promises.length === 0 && resolve(promises);
      // 4.等待全部敲定
      const result = [];
      let count = 0;
      promises.forEach((p, index) => {
        MyPromise.resolve(p).then(
          (res) => {
            // 4.1记录结果
            result[index] = { status: FULFILLED, value: res }; // 4.2 处理兑现{ status: FULFILLED, value: res }
            // 记录敲定的次数
            count++;
            // 不论成功失败都是resolve
            count === promises.length && resolve(result);
          },
          (err) => {
            // 4.1记录结果
            result[index] = { status: REJECTED, reason: err }; // 4.3处理拒绝{ status: REJECTED, reason: err }
            // 记录敲定的次数
            count++;
            // 不论成功失败都是resolve
            count === promises.length && resolve(result);
          }
        );
      });
    });
  }
// 测试代码
const p1 = MyPromise.resolve(1);
const p2 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    // resolve("ok");
    reject("err");
  }, 1000);
});
const p3 = "贾公子";
const p = MyPromise.allSettled([p1, p2, p3]);
// const p = MyPromise.allSettled();
// const p = MyPromise.allSettled([]);

p.then(
  (res) => {
    console.log("res:", res);
  },
  (error) => {
    console.log("err:", error);
  }
);

any

Promise.any() 静态方法将一个 Promise 可迭代对象作为输入,并返回一个 promise 当输入的任何一个 Promise 兑现时,这个返回的 Promise 将会兑现,并返回第一个兑现的值。当所有输入 Promise 都被拒绝(包括传递了空的可迭代对象)时,它会以一个包含拒绝原因数组的 AggregateErrorAggregateErrorAggregateError 拒绝。

AggregateError 对象代表了包装了多个错误对象的单个错误对象。当一个操作需要报告多个错误时,例如 promise.any,当传递给它的所有承诺都被拒绝时,就会抛出该错误。

 * 参数:promise数组

 * 结果

 *    获取到第一个成功的结果

 *    获取到所有拒绝失败的原因 AggregateError: All promises were rejected[拒绝原因1,拒绝原因n]

 *    传入空数组,直接拒绝 AggregateError: All promises were rejected[]

 *    不传入数组直接报错

 

  • 1.返回promise 
  • 2.数组判断 错误信息 Argument is not iterable
  • 3.空数组直接拒绝 AggregateError([错误原因],All promises were rejected[)
  • 4.等待结果
  • 4.1第一个兑现
  • 4.2全部拒绝 
  static any(promises) {
    // 1.返回promise
    return new Promise((resolve, reject) => {
      // 2.数组判断 错误信息 Argument is not iterable
      if (!Array.isArray(promises)) {
        return reject(new TypeError("Argument is not iterable"));
      }
      // 3.空数组直接拒绝 AggregateError([错误原因],All promises were rejected[)
      promises.length === 0 &&
        reject(new AggregateError(promises, "All promises were rejected"));
      const errors = [];
      let count = 0;
      // 4.等待结果
      promises.forEach((p, index) => {
        MyPromise.resolve(p).then(
          (res) => {
            // 4.1第一个兑现
            resolve(res);
          },
          (err) => {
            // 4.2全部拒绝
            errors[index] = err;
            count++;
            count === promises.length &&
              reject(new AggregateError(errors, "All promises were rejected"));
          }
        );
      });
    });
  }
// 测试代码
const p1 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    // resolve("ok");
    reject("err1");
  }, 1000);
});
const p2 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    // resolve("ok");
    reject("err2");
  }, 2000);
});
// const p3 = "贾公子";
const p3 = MyPromise.reject("贾公子");

const p = MyPromise.any([p1, p2, p3]);
// const p = MyPromise.any();
// const p = MyPromise.any([]);

p.then(
  (res) => {
    console.log("res:", res);
  },
  (error) => {
    // console.log("err:", error);
    console.dir(error);
  }
);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1244299.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jjwt使用说明-笔记

jjwt官网链接&#xff1a;https://github.com/jwtk/jjwt POM 依赖 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.12.3</version> </dependency> <dependency><grou…

会议动态 | 祝贺2023 中国商品混凝土年会在上海隆重召开!

2023年11月19日-21日&#xff0c;由&#xff08;国家&#xff09;建筑材料工业技术情报研究所、中国散装水泥推广发展协会混凝土专委会主办的"笃信固本 行稳致远"——2023 第十九届全国商品混凝土可持续发展论坛暨2023中国商品混凝土年会在上海隆重召开&#xff01; …

什么是指针碰撞

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

Shell 通配符与正则表达元字符

Author&#xff1a;rab 目录 前言一、通配符1.1 *1.2 ?1.3 []1.4 {} 二、正则表达元字符2.1 *2.2 .2.3 ^2.4 $2.5 []2.6 \2.7 \<\>2.8 \{\} 总结 前言 不管是学任何语言&#xff0c;几乎都会涉及到通配符与正则的使用。有时候对于 Linux 初学者来说&#xff0c;往往会将…

线上问题排查实例分析|关于 Redis 内存泄漏

Redis 作为高性能的 key-value 内存型数据库&#xff0c;普遍使用在对性能要求较高的系统中&#xff0c;同时也是滴滴内部的内存使用大户。本文从 KV 团队对线上 Redis 内存泄漏定位的时间线维度&#xff0c;简要介绍 Linux 上内存泄漏的问题定位思路和工具。 16:30 问题暴露 业…

gitt开源项目的意义,公司为什么会对在gitt上有开源项目的人更大机会

Git是一种分布式版本控制系统&#xff0c;它可以帮助程序员管理代码的历史版本和协同工作。同时&#xff0c;Git也成为了开源项目的主要托管平台之一。Git的开源项目意义重大&#xff0c;因为这种开源项目托管平台可以帮助开发者将代码和项目分享给全球的开发者&#xff0c;并且…

linux网络之网络层与数据链路层

文章目录 一、网络层 1.IP协议 2.IP协议头格式 3.网段划分 4.特殊ip地址 5.IP地址的数量限制 6.私有ip和公网IP 7.路由 二、数据链路层 1.以太网 2.以太网帧格式 3.MAC地址 4.对比理解MAC地址和IP地址 5.MTU 6.ARP协议 ARP协议的工作流程 ARP数据报的格式 7.DNS 8.ICMP协议 9.N…

从六个方面对比Go和Python的差异

您是否想过 Go 与 Python 之间的主要区别是什么&#xff1f;随着对软件开发人员的需求不断增加&#xff0c;选择哪种编码语言可能会很困难。 ​ 在此&#xff0c;我们将从六个方面对比Go和Python,探讨 Go 和 Python之间的差异。我们将讨论它们的特点、优缺点&#xff0c;以便…

mongodb数据库的常用操作语句

说在前面的话 本文所有的操作示例&#xff0c;都以集合“HistoryTaskBase”为例。 一、查询 1、时间区间 查询“通知时间”介于2019-09-01到2019-10-01之间的数据。 db.getCollection(HistoryTaskBase).find({notifyTime:{$gte:ISODate(2019-09-01T00:00:00.000Z),$lte:ISOD…

Nginx:简介、安装与部署

一、Nginx简介 Nginx是一个很好的高性能Web和反向大力服务器&#xff0c;它具有很多非常优越的特性&#xff1a;在高连接并发的情况下&#xff0c;Nginx是Apahe服务器的不错的替代品&#xff1a;Nginx在美国是虚拟主机生意选择的软件平台之一。能够支持50000个并发连接数的响应…

《洛谷深入浅出基础篇》P4017最大食物链————拓扑排序

上链接&#xff1a;P4017 最大食物链计数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P4017 上题干&#xff1a; 题目背景 你知道食物链吗&#xff1f;Delia 生物考试的时候&#xff0c;数食物链条数的题目全都错了&#xff0c;因为她总是…

高质量短效SOCKS5代理IP是什么意思?作为技术你了解吗

小张是一位网络安全技术测试员&#xff0c;最近他接到了一个头疼的任务&#xff0c;那就是评估公司系统的安全性&#xff0c;因此他前来咨询&#xff0c;在得知SOCKS5代理IP可以帮他之后&#xff0c;他不禁产生疑问&#xff0c;这是什么原理&#xff1f;其实和小张一样的朋友不…

ELK企业级日志分析平台——kibana数据可视化

部署 新建虚拟机server5&#xff0c;部署kibana [rootelk5 ~]# rpm -ivh kibana-7.6.1-x86_64.rpm [rootelk5 ~]# cd /etc/kibana/[rootelk5 kibana]# vim kibana.ymlserver.host: "0.0.0.0"elasticsearch.hosts: ["http://192.168.56.11:9200"]i18n.local…

嵌入式开发从入门到入土

写在前面的话 嵌入式开发涉及的层面很广&#xff0c;它既有底层硬件的开发&#xff0c;又涉及上层应用的开发&#xff0c;也就是所谓的系统集成的硬件和软件。而C语言不仅具有汇编语言操作底层的优势&#xff0c;又具有高级开发语言的功能性强的特点&#xff0c;当之无愧地成为…

JavaScript框架 Angular、React、Vue.js 的全栈解决方案比较

在 Web 开发领域&#xff0c;JavaScript 提供大量技术栈可供选择。其中最典型的三套组合&#xff0c;分别是 MERN、MEAN 和 MEVN。前端框架&#xff08;React、Angular 和 Vue&#xff09;进行简化比较。 MERN 技术栈详解 MERN 技术栈包含四大具体组件&#xff1a; MongoDB&am…

保姆级 Keras 实现 YOLO v3 一

保姆级 Keras 实现 YOLO v3 一 一. YOLO v3 总览二. 特征提取网络特征提取网络代码实现 三. 特征融合特征融合代码实现 四. 网络输出模型输出代码实现 五. 网络模型代码实现六. 代码下载 如果要给 YOLO 目标检测算法一个评价的话, 就是快和准, 现在已经到了 v8, 但是我为什么还…

前端环境变量释义process.env与import.meta.env

视频教程 彻底搞懂前端环境变量使用和原理&#xff0c;超清楚_哔哩哔哩_bilibili 添加命令行参数 --modexxxxx 新建.env.xxxx文件,其中.env文件会在所有环境下生效 以VITE_开头&#xff0c;字符串无需加双引号 使用import.meta.env.VITE_xxxxx进行调用

JavaScript基础—引入方式、注释和结束符、输入和输出、变量、常量、数据类型、检测数据类型、类型转换、综合案例—用户订单信息

版本说明 当前版本号[20231123]。 版本修改说明20231123初版 目录 文章目录 版本说明目录JavaScript 基础 - 第1天介绍引入方式内部方式外部形式 注释和结束符单行注释多行注释 结束符输入和输出输出输入 变量声明赋值变量初始化更新变量 关键字变量名命名规则 常量数据类型…

2023年11个最佳免费WordPress主题

如果您刚刚开始使用 WordPress&#xff0c;您可能会很自然地认为&#xff0c;只要免费的WordPress主题看起来像您想要的网站主题&#xff0c;那么它就很合适。不幸的是&#xff0c;事情并没有那么简单。这就是为什么在今天的文章中&#xff0c;我们概述了一份可靠的标准清单&am…

投资房产的理由与好处,投资买房的方法与技巧

一、教程描述 本套买房教程&#xff0c;大小2.15G&#xff0c;共有23个文件。 二、教程目录 00.她23岁北漂月薪600&#xff0c;7年后50万在京买了第一套房&#xff0c;如今身价上千万.mpg 01.这个游戏&#xff0c;有些人输了所有钱&#xff0c;一辈子也不明白这个道理.mpg …