手动实现promise的all,race,finally方法
Promise.all
是一个非常有用的工具,它接受一个 Promise 对象数组,并返回一个新的 Promise。当所有输入的 Promise 都成功解决时,新的 Promise 会解决为一个包含所有结果的数组;如果任何一个 Promise 被拒绝,新的 Promise 会立即被拒绝,并返回第一个被拒绝的错误。
function myPromiseAll(promiseArray) {return new Promise((resolve, reject) => {//1.参数检查://检查传入的参数是否为数组,如果不是数组,则抛出 TypeError。if (!Array.isArray(promiseArray)) {return reject(new TypeError("arguments must be an array"))}//2.初始化://创建一个 results 数组来存储每个 Promise 的结果。//初始化 count 计数器,用于记录已经完成的 Promise 数量。//获取 promises 数组的总长度 len。let result = []let count = 0const len = promiseArray.length//3.特殊情况处理://如果 promises 数组为空,直接返回一个已解决的 Promise,其结果为一个空数组。if (len === 0) {resolve(result)}//4.遍历 Promise 数组://使用 for循环 遍历 promises 数组。//对每个 Promise 使用 Promise.resolve 确保它是 Promise 对象。//使用 then 方法处理每个 Promise 的成功和失败情况://成功时,将结果存储在 results 数组中,并增加 count。//如果 count 达到 len,说明所有 Promise 都已成功解决,调用 resolve 方法,传递 results 数组。//失败时,立即调用 reject 方法,传递错误信息。for (let i = 0; i < len; i++) {Promise.resolve(promiseArray[i]).then((res) => {result[i] = rescount++if (count === len) {resolve(result)}}).catch((err) => reject(err))}})}// 示例代码const promise1 = Promise.resolve(1);const promise2 = Promise.resolve(2);const promise3 = new Promise((resolve) => setTimeout(() => resolve(3), 1000));const promise4 = Promise.reject('Error');myPromiseAll([promise1, promise2, promise3]).then((results) => {console.log('All promises resolved:', results); // 输出: All promises resolved: [1, 2, 3]}).catch((error) => {console.error('An error occurred:', error);});myPromiseAll([promise1, promise2, promise4]).then((results) => {console.log('All promises resolved:', results);}).catch((error) => {console.error('An error occurred:', error); // 输出: An error occurred: Error});
Promise.race
接受一个 Promise 对象数组,并返回一个新的 Promise。新的 Promise 会在第一个输入的 Promise 被解决或拒绝时立即解决或拒绝,其结果或错误信息取决于第一个完成的 Promise。
function myPromiseRace(promiseArray) {return new Promise((resolve, reject) => {//1.参数检查://检查传入的参数是否为数组,如果不是数组,则抛出 TypeError。if (!Array.isArray(promiseArray)) {return reject(new TypeError("arguments must be an array"))}//2.遍历 Promise 数组://使用 for 循环遍历 promises 数组。//对每个 Promise 使用 Promise.resolve 确保它是 Promise 对象。//使用 then 方法处理每个 Promise 的成功和失败情况://成功时,立即调用 resolve 方法,传递结果值。//失败时,立即调用 reject 方法,传递错误信息。for (let i = 0; i < promiseArray.length; i++) {//写法一:Promise.resolve(promiseArray[i]).then((res) => {resolve(res)},(error) => {reject(error)})//写法二://Promise.resolve(promiseArray[i]).then(resolve, reject)}})}// 示例代码const promise1 = Promise.resolve(1);const promise2 = new Promise((resolve) => setTimeout(() => resolve(2), 1000));const promise3 = new Promise((resolve) => setTimeout(() => resolve(3), 500));const promise4 = Promise.reject('Error');myPromiseRace([promise1, promise2, promise3]).then((result) => {console.log('First resolved promise:', result); // 输出: First resolved promise: 1}).catch((error) => {console.error('An error occurred:', error);});myPromiseRace([promise2, promise3, promise4]).then((result) => {console.log('First resolved promise:', result);}).catch((error) => {console.error('An error occurred:', error); // 输出: An error occurred: Error});
Promise.finally
用于指定不管 Promise 最终状态如何,都会执行的操作。这个方法通常用于清理工作,比如关闭文件句柄、清除定时器等。
正常使用:
promise.then((result) => {// 处理已解决的情况}).catch((error) => {// 处理已失败的情况}).finally(() => {// 不管Promise对象最终的状态如何,都会执行的回调函数});
手动实现:
function myPromiseFinally(promise, callback) {return promise.then(//接受两个参数:一个 Promise 对象 promise 和一个回调函数 callback。//使用 then 方法分别处理 promise 的成功和失败情况。//在成功的情况下,先调用 callback 回调函数,然后返回原始的成功值。//在失败的情况下,先调用 callback 回调函数,然后重新抛出原始的错误。(value) => Promise.resolve(callback()).then(() => value),(error) =>Promise.resolve(callback()).then(() => {throw error}))}//示例代码:
const promise1 = Promise.resolve(1);
const promise2 = new Promise((resolve) => setTimeout(() => resolve(2), 1000));
const promise3 = new Promise((resolve, reject) => setTimeout(() => reject('Error'), 500));// 成功的情况
myPromiseFinally(promise1, () => {console.log('Finally block executed');
}).then((result) => {console.log('Result:', result); // 输出: Result: 1
}).catch((error) => {console.error('Error:', error);
});// 延迟成功的情况
myPromiseFinally(promise2, () => {console.log('Finally block executed');
}).then((result) => {console.log('Result:', result); // 输出: Result: 2
}).catch((error) => {console.error('Error:', error);
});// 失败的情况
myPromiseFinally(promise3, () => {console.log('Finally block executed');
}).then((result) => {console.log('Result:', result);
}).catch((error) => {console.error('Error:', error); // 输出: Error: Error
});
相关文章:
手动实现promise的all,race,finally方法
Promise.all 是一个非常有用的工具,它接受一个 Promise 对象数组,并返回一个新的 Promise。当所有输入的 Promise 都成功解决时,新的 Promise 会解决为一个包含所有结果的数组;如果任何一个 Promise 被拒绝,新的 Prom…...

H5移动端预览PDF方法
新建页面 新建一个页面以便去预览对应的pdf 新建完后在 pages.json 文件内去新增对应路由 页面内容 <template><view class"page"><view class"pdf"><view id"demo"></view></view><view class"b…...

uniapp—android原生插件开发(1环境准备)
本篇文章从实战角度出发,将UniApp集成新大陆PDA设备RFID的全过程分为四部曲,涵盖环境搭建、插件开发、AAR打包、项目引入和功能调试。通过这份教程,轻松应对安卓原生插件开发与打包需求! 项目背景: UniApp集成新大陆P…...

《潜行者2切尔诺贝利之心》游戏引擎介绍
潜行者2切尔诺贝利之心是基于虚幻5引擎,所以画面效果大家不必担心。游戏目前已经跳票了很久,预计发售时间是2024 年 11 月 21 日,这次应该不会再跳票。 潜行者2切尔诺贝利之心是虚幻5吗 答:是虚幻5。 潜行者官方推特之前回复了…...
winform 加载 office excel 插入QRCode图片如何设定位置
需求:winform 加载 office excel 并加载QRCode图片,但是每台PC打印出来QRCode位置都不太一样,怎么办呢? 我的办法: 1、在sheet中插入一个 textbox ,改名 qrcode (这个名字随便设置)…...

简易入手《SOM神经网络》的本质与原理
原创文章,转载请说明来自《老饼讲解神经网络》:www.bbbdata.com 关于《老饼讲解神经网络》: 本网结构化讲解神经网络的知识,原理和代码。 重现matlab神经网络工具箱的算法,是学习神经网络的好助手。 目录 一、入门原理解说 01.…...

21.assert断言
assert(断言)主要用于在程序运行过程中检查某个条件是否满足,如果不满足则会触发错误并终止程序执行,可以帮助程序员在开发阶段及时发现可能存在的逻辑错误等问题。 通过断言调试程序,abotr() has been called 就是断言…...
15分钟学 Go 第 46 天 : 监控与日志
第46天:监控与日志 学习目标 了解如何实现应用监控与日志管理,掌握相关工具和最佳实践。 内容结构 引言监控的概念与工具 监控的定义常见监控工具 日志管理的概念与工具 日志的重要性常见日志管理工具 实现监控与日志的最佳实践 监控指标日志格式 实战…...

BFS 算法专题(四):多源 BFS
目录 1. 01 矩阵 1.1 算法原理 1.2 算法代码 2. 飞地的数量 2.1 算法原理 2.2 算法代码 3. 地图中的最高点 3.1 算法原理 3.2 算法代码 4. 地图分析 4.1 算法原理 4.2 算法代码 1. 01 矩阵 . - 力扣(LeetCode) 1.1 算法原理 采用 BFS 正难…...

基于Spring Boot+Vue的养老院管理系统【原创】
一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构:B/S架构 运行环境:win10/win11、jdk17 前端: 技术:框架Vue.js;UI库:ElementUI; 开发工具&…...
Linux screen和cscope工具使用总结
1 minicom使用 1.1 minicom配置 第一次启动时: 如果输入sudo minicom提示错误,则需: sudo minicom -s 启动 出现配置菜单:选serial port setup 进入串口配置 输入A配置串口驱动为/dev/ttyUSB0 输入E配置速率为115200 8N1 输入F将 …...
深度学习面试八股汇总
按序发布: 深度学习——优化算法、激活函数、归一化、正则化 进入 深度学习——权重初始化、评估指标、梯度消失和梯度爆炸 进入 深度学习——前向传播与反向传播、神经网络(前馈神经网络与反馈神经网络)、常见算法 进入 深度学习——卷积神…...
微服务架构面试内容整理-API 网关-Gateway
Spring Cloud Gateway 是一个用于构建 API 网关的框架,它为微服务架构提供了灵活的路由和过滤功能。作为 Spring Cloud 生态的一部分,Gateway 提供了易于使用的 API 和强大的功能,适合用于现代微服务架构中的请求管理和服务交互。以下是 Spring Cloud Gateway 的主要特点、工…...

22.04Ubuntu---ROS2使用rclcpp编写节点C++
节点需要存在于功能包当中,功能包需要存在于工作空间当中。 所以我们要想创建节点,就要先创建一个工作空间,再创建功能包。 第一步:创建工作空间 mkdir -p chapt2_ws/src/ 第二步:创建example_cpp功能包,…...
XML 现实案例:深入解析与应用
XML 现实案例:深入解析与应用 XML(可扩展标记语言)自1998年成为W3C推荐标准以来,一直是数据交换和存储的重要工具。它是一种用于标记电子文件的结构化语言,使得数据不仅人类可读,而且机器可处理。本文将探讨XML在现实世界中的应用案例,展示其如何在不同领域中发挥作用。…...

Spring源码(十二):Spring MVC之Spring Boot
本篇将详细讨论Spring Boot 的启动/加载、处理请求的具体流程。我们先从一个简单的Spring Boot项目日志开始分析(这里假设读者已经仔细阅读完了前面的文章,且对Spring源码有一定深度的了解,否则会看得一脸懵逼)。 本文为2024重置…...
Kafka 之事务消息
前言: 在分布式消息系统中,事务消息也是一个热门课题,在项目的实际业务场景中,如果用到事务消息的场景也不少见,那 Kafka 作为一个高性能的分布式消息中间件,同样也支持事务消息,本篇我们将对 …...

小菜家教平台(四):基于SpringBoot+Vue打造一站式学习管理系统
前言 昨天配置完了过滤器,权限检验,基本的SpringSecurity功能已经配置的差不多了,今天继续开发,明天可能会暂停一天整理一下需求,然后就进行CRUD了。 今日进度 补充SpringSecurity异常处理和全局异常处理器 详细操作…...

解决 Vue3、Vite 和 TypeScript 开发环境下跨域的问题,实现前后端数据传递
引言 本文介绍如何在开发环境下解决 Vite 前端(端口 3000)和后端(端口 80)之间的跨域问题: 在开发环境中,前端使用的 Vite 端口与后端端口不一致,会产生跨域错误提示: Access to X…...
量化交易系统开发-实时行情自动化交易-3.3.数据采集流程
19年创业做过一年的量化交易但没有成功,作为交易系统的开发人员积累了一些经验,最近想重新研究交易系统,一边整理一边写出来一些思考供大家参考,也希望跟做量化的朋友有更多的交流和合作。 接下来说说数据采集流程,后…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...

表单设计器拖拽对象时添加属性
背景:因为项目需要。自写设计器。遇到的坑在此记录 使用的拖拽组件时vuedraggable。下面放上局部示例截图。 坑1。draggable标签在拖拽时可以获取到被拖拽的对象属性定义 要使用 :clone, 而不是clone。我想应该是因为draggable标签比较特。另外在使用**:clone时要将…...