手动实现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年创业做过一年的量化交易但没有成功,作为交易系统的开发人员积累了一些经验,最近想重新研究交易系统,一边整理一边写出来一些思考供大家参考,也希望跟做量化的朋友有更多的交流和合作。 接下来说说数据采集流程,后…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
