多个promise并发执行,如果某个promise失败,则尝试重新执行该promise一次,如果还是失败则提示错误

2023-10-27

思路

可以使用 Promise.all()和Promise.catch() 结合的方式来实现多个promise的并发执行,并在某个promise失败时尝试重新执行。

首先,将所有的promise放入数组中,并使用Promise.all()来同时执行这些promise,这样可以确保所有的promise都成功执行。

然后,通过catch()方法来捕获拒绝的promise,并在捕获到之后进行重新执行。

代码

const promise1 = () => Promise.resolve(1);
let isFirst = true;
const promise2 = () =>
  new Promise((resolve, reject) => {
    console.log('promise2 isFirst:', isFirst);
    if (isFirst) {
      // 模拟promise第一次执行失败,第二次执行成功
      reject('2 error');
      isFirst = false;
    }
    resolve('2 success');
  });
const promise3 = () => Promise.resolve(3);

const promises = [promise1, promise2, promise3];

Promise.all(
  promises.map(promise => {
    return promise().catch(error => {
      // 如果失败则重新执行该promise
      console.error('Promise failed, retrying...:');
      return promise();
    });
  })
)
  .then(res => {
    console.log('All promises succeeded: ', res);
  })
  .catch(error => console.error('All promises failed'));

打印结果:

在这里插入图片描述

进一步完善

封装一个wrap函数,统一处理失败后重试的这段逻辑,不需要再放在promise.all里面,这样子提高这些promise的可扩展性。

const wrap = (func) => {
  // 调用wrap函数,会立即执行func
  let last = func();
  // 使用闭包,返回一个函数
  return () =>
    last.catch(() => { 
      // 失败之后,重新执行func,并保存在last,这样可以保证所有promise只会被执行一次
      // 比如某个promise第一次执行失败,重试成功,last将会保存成功后的promise,下次使用到的时候就是返回成功后的这个promise
      last = func();
      return last.catch(() => {
        // will throw error if second failed
        throw new Error('second execute failed');
      });
    });
};

const promise1 = wrap(() => Promise.resolve(1));
let isFirst = true;
const promise2 = wrap(
  () =>
    new Promise((resolve, reject) => {
      console.log('promise2 isFirst:', isFirst);
      if (isFirst) {
        reject('2 error');
        isFirst = false;
      }
      resolve('2 success');
    })
);
const promise3 = wrap(() => Promise.resolve(3));

const promises = [promise1, promise2, promise3];

Promise.all(promises.map(promise => promise()))
  .then(res => {
    console.log('All promises succeeded: ', res);
  })
  .catch(error => console.error('All promises failed'));

打印结果:

在这里插入图片描述

补充(Promise.allSettled())

官方:Promise.allSettled()
Promise.allSettled来判断多个Promise的执行结果,包括成功和失败。Promise.allSettled返回一个新的Promise对象,该对象在所有给定的Promise已被决议或拒绝后完成,并带有一个对象数组,每个对象表示对应的Promise结果

例子:

const promises = [promise1, promise2, promise3];

Promise.allSettled(promises)
  .then(results => {
    results.forEach((result, index) => {
      if (result.status === 'fulfilled') {
        console.log(`Promise ${index + 1} fulfilled with value:`, result.value);
      } else {
        console.log(`Promise ${index + 1} rejected with reason:`, result.reason);
      }
    });
  });

在上述例子中,promises数组包含多个Promise对象。Promise.allSettled等待所有Promise对象都被决议或拒绝后,返回一个结果数组。结果数组中的每个对象包含了对应Promise的状态和结果。使用forEach循环遍历结果数组,根据状态输出相应的信息。

注意:Promise.allSettled是ES2020中新增的方法,如果需要在较旧的环境中使用该方法,可以使用Promise.all和Promise.catch的组合来实现类似的功能。

该方法是Promise 并发Promise.allSettled()方法之一。当您有多个不依赖于彼此才能成功完成的异步任务,或者您总是想知道每个 Promise 的结果时,通常使用Promise.allSettled()。

相比之下,Promise.all()如果任务相互依赖,或者如果您想在其中任何一个任务拒绝时立即拒绝,则返回的 Promise 可能更合适。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多个promise并发执行,如果某个promise失败,则尝试重新执行该promise一次,如果还是失败则提示错误 的相关文章

  • 使用 fb.ui 时如何检测用户取消共享

    我正在使用提供的文档here https developers facebook com docs sharing reference share dialog使用以下代码 共享对话框正确显示 问题是我无法区分用户在对话框中执行的 取消 和
  • 使用 JavaScript 以编程方式编辑 Google 文档

    我想做的是运行一些 JavaScript 代码 将文本输入到 Google 文档中 到目前为止 我所做的是在我的个人网页上创建一个嵌入 Google 文档的 iframe 元素 目前我想做的是使用 Google 源代码中的函数来输入文本 当
  • 将 JavaScript 数组转换为具有属性的数组

    我有一个像这样的数组从服务器返回响应 111 1010 111 1010 1010 我想将其转换为 JavaScript JSON 如下所示 branch 111 branch 1010 branch 111 branch 1010 bra
  • 循环选项在 youtube js api 中不起作用

    我想知道为什么我的代码不循环播放视频 除了循环选项之外 一切正常 我真的需要它 多谢 div You need Flash player 8 and JavaScript enabled to view this video div
  • 通过 declarativeNetRequest + extensionPath 重定向时获取原始 URL

    我需要在导航时但在用户从使用设置的规则重定向之前获取 chrome 选项卡的 urldeclarativeNetRequest 目前 用户可以使用上下文菜单添加规则 当尝试访问过滤的主机时 它将被重定向到内部扩展页面 chrome cont
  • 计算 HH:MM:SS 中两个日期之间的时间差 javascript

    我用 JavaScript 创建了一个计时器应用程序 首先 它使用当前的 UTC 日期来初始化计时器并提供一些参考 这是代码 on timer function e var self this if e target hasClass pt
  • YouTube 360​​ 视频 iframe 无法在移动浏览器中工作

    我正在尝试为 YouTube 360 视频获取嵌入的 iframe 以便在我的移动网站上播放 它在桌面浏览器上运行良好 但在移动浏览器中我只能播放平面立体视图 我可以确认它绝对是一个 HTML5 播放器 这显然是其他人正在经历的一个未解决的
  • Chart.js 渲染垂直堆积条形图太慢

    我正在使用 Chart js API 渲染多个堆叠的垂直条形图 但性能很慢 我什至做了一些改变 这样所有的content对象已经由服务器而不是浏览器处理 但我意识到大部分时间来自最终函数new Chart overallStatsChart
  • 将表单传递给 AngularJS 组件进行验证

    我正在将旧代码库迁移到 AngularJS 1 5 所推广的新组件架构 我在对较大的表单执行此操作时遇到了问题 传统上 我会附加表单验证 如下所示
  • 如何使用 javascript/ASP.NET/CSS 旋转和淡入淡出背景图像

    我需要随机淡入淡出背景图像 这将是一个定时函数 例如每 5 秒一次 我需要使用 ASP NET Javascript CSS 或全部三者来完成此操作 请大家帮帮我 谢谢 Cycle 一个 jQuery 插件 是一个非常灵活的图像旋转解决方案
  • 在多个 angular.js 应用程序之间共享单个服务

    我正在构建一个电子商务网站 基于 shopify 并且使用多个小型 angularjs 应用程序来处理诸如快速购物车 愿望清单 过滤产品和其他一些较小项目之类的事情 我最初使用了一个大型应用程序 具有路由和所有内容 但当我没有完整的 RES
  • 将 MVC 操作结果发送到打印机

    我有一个带有操作的控制器 SomeController ActionToBePrinted ActionToBePrinted 返回一个 html 视图 当按下按钮时 从普通的 mvc razor 视图调用此操作 当按下按钮时 我将如何将视
  • 使用 Moment.js 从 ISO 字符串中提取 utcOffset

    使用 moment js 我尝试从 ISO 日期字符串中提取偏移量 以便稍后在格式化纪元时间戳时使用该偏移量 以确保时间戳的转换位于同一时区 即使字符串中的偏移量为 0400 结果始终为0 var currentTime 2015 03 1
  • React-Router v5 History.push 不触发组件

    很抱歉朋友们又问这个问题了 我找到了解决这个问题的几个方法 但他们让我很困惑 我只是想问一个优雅的方法来做到这一点 正如你通过标题所理解的 我有一个关于反应路由的问题 让我解释 我有一个按钮 其名称是Login 单击按钮后 我执行了一些逻辑
  • 节省页面加载时间的提示[重复]

    这个问题在这里已经有答案了 我的问题 削减那些不必要的 kb 并使页面加载速度更快的最佳方法是什么 全部是什么优化实践 编码实践 在js php中 如果执行可以使您的页面更轻 为什么我问这个 我读了这篇关于 jquery js 与 jque
  • setTimeout() 的问题

    这是我的代码 我想要它做的是写 0 等待一秒 写 1 等待一秒 写 2 等待一秒 等等 而是写 5 5 5 5 5 for i 0 i lt 5 i setTimeout document write i 1000 http jsfiddl
  • Ajax调用完成后执行函数

    我是 Ajax 新手 我尝试在使用 for 循环时使用 Ajax Ajax 调用之后 我正在运行一个使用 Ajax 调用中创建的变量的函数 该函数只执行两次 我认为 Ajax 调用可能没有足够的时间在循环开始之前进行调用 有没有办法在运行
  • 为什么react中的组件需要大写? [复制]

    这个问题在这里已经有答案了 因此 当您声明一个组件以小写首字母进行反应时 它不会显示 也不会引发错误 当您将组件名称大写时 它确实有效 这样的实现是怎样的呢 为了避免与现有的 html 元素发生冲突 还是这是一个错误 var test Re
  • javascript捕获文本区域中的粘贴事件

    我目前有一个文本区域 我需要控制已粘贴的文本 本质上 我需要能够将用户想要粘贴到文本区域中的任何内容并将其放入变量中 然后我将计算出他们粘贴文本的位置和字符串的大小 以将其从文本区域中删除 然后最后用我自己的方式处理变量中的文本 我的问题
  • Page_ClientValidate 正在验证多次。

    我的问题是 验证摘要消息 警报 显示两次 我无法弄清楚原因 请帮忙 这是代码 function validate javascript function if typeof Page ClientValidate function var

随机推荐

  • 初识网络原理

    确定不来看看新出炉的知识 目录 1 网络互连 1 1局域网 1 2广域网 2 网络通信基础 2 1IP地址 2 2端口号 3 认识协议 3 1五元组 3 2协议分层 3 3OSI 7层模型 3 4TCP IP5层 或5层 模型 3 5网络设
  • 请求参数默认值多种实现方式

    文章目录 1 直接赋值 2 使用切面实现默认值 自定义注解 切面类 控制层使用 效果展示 3 使用过滤器Filter实现 自定义请求体 自定义过滤器 1 直接赋值 当前页码 private int pageNum 1 每页条数 privat
  • idea快速清理无效类文件

    1 右击选中的项目 如下图所示 2 在弹出框中输入 unused declaration点击选择 如下图所示 3 弹出如下图所示 点击ok 此时需要一段时间 4 结果如下图所示 5 此时 一个个选中 然后双击 有4种处理模式 如下图所示 S
  • 基于Distflow的最优潮流模型(OPF)--模型推导篇

    开篇 前言 自打上期内容火电机组经济调度建模及求解 基础篇推出以后 有小伙伴留言 不考虑潮流问题的经济调度都是耍流氓 作为一个有文化的流氓 我们尝试着为大家科普潮流计算 对于电力系统而言 潮流计算是一个非常复杂且重要内容 如果我们推文中有什
  • 俞敏洪:与其有钱,不如值钱

    很多人一辈子有两个追求 一个是有钱 一个是值钱 有的人运气好 出生在富贵之家 一出生就像贾宝玉一样嘴里含着玉 有钱就不是问题 但有钱解决不了第二个问题 也就是你本人值不值钱的问题 值钱是个人价值的体现 比如你去找一份工作 人家给你开出百万年
  • 链表 List.h

    链表 List h include list h include
  • Android指纹门锁ESP32项目

    本教程中我向您展示如何使用指纹扫描仪Android手机通过ESP32或ESP8266 Wifi或Arduino wifi模块进行门解锁 要创建此项目 您需要ESP32 中继模块 电磁门锁和Android手机 所需零件 源代码 详情参阅 亚图
  • layUI 使用select选择框无法显示出样式,看不到、等解决方案

    我们在写layui代码时候可能遇到这样的问题 明明代码都是从layui官网上复制下来的 却还是会看不到相应的元素 就比如我昨天遇到的一个BUG 代码如上 但是页面上却没有显示出选择框 选择框这里却依然没有结果出现 这个问题困扰了我几个小时
  • js下载base64格式的图片

    步骤 1 创建一个a标签 2 给a标签创建点击事件 3 将base64数据转为Blob类型 4 将a标签的href指向Blob类型数据 5 触发a标签 代码 template vue qr 组件可以自动将 text绑定的url地址转换为二维
  • 【Python零基础入门篇 · 9】:字典的相关操作

    文章目录 字典 键 值 字典的基本格式 字典的定义 键值对 键的唯一性 字典的常见操作一 增删改查 查看元素 根据键名返回值 删除元素 del clear 修改元素 添加元素 字典中的常见操作二 len 求长度 dict keys dict
  • SQL语句:查询数据表的前n行信息

    每种数据库使用的关键字都不一样 每种数据库使用的关键字都不一样 每种数据库使用的关键字都不一样 SQL Server MS Access 语法 TOP SELECT TOP number percent column name s FROM
  • Java 模拟百度翻译

    相信百度翻译对于大家来说并不陌生 本案例要求编写一个程序模拟百度翻译 用户输入英文之后搜索程序中对应的中文 如果搜索到对应的中文就输出搜索结果 反之给出提示 package demo52 import java util HashMap i
  • sv面向对象:类

    写在前面 开始修炼 类是通过代码怎么体现 实例1 定义一个类 systemverilog绿皮书 例5 1简单的 Transaction类 class Transaction bit 31 0 addr crc data 8 class pr
  • Tomcat配置SSL证书

    本地配置ssl证书 为了更好的再服务器上配置ssl证书 先在本上上熟悉流程 本地不需要类似阿里云的证书 借助java的keytool帮助生成离线的证书 keytool genkey alias ceshi storetype PKCS12
  • MVC和MVVM【区别和详解】

    本篇文章的主要内容是给大家讲解一下MVC与MVVM思想之间的区别 希望能对你有所帮助 他们的区别主要在于MVC中Controller 控制层 变成了MVVM中的viewModel 双向数据绑定 MVVM解决了MVC中需要大量操作DOM所带来
  • std : : vector

    一 简介 std vector 的底层实现通常基于动态数组 dynamic array 它是一种连续分配的内存块 允许元素的快速随机访问 下面是 std vector 的一些关键特点和底层实现细节 连续内存块 std vector 内部使用
  • 【从零学习openCV】ubuntu+openCV+qt安装配置

    一 Ubuntu安装 ubuntu是linux的一个发行版本 我想对linux有所了解的人应该都知道 我们直接到官网上下载就好了 是免费使用的 官网下载链接 这里我用的是最新的ubuntu14 04 由于我用的是Mac系统 直接用Vmwar
  • Windows中一些宏的含义

    1 WIN32 WINDOWS WIN32 WINNT WINVER 这三个宏其实都是Windows的版本宏 在Windows 95 98 Me这一分支的OS中 Windows的定义的版本宏是 WIN32 WINDOWS 与此同时 Wind
  • net : 无法将“net”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然 后

    可能是系统的环境变量没有配置好 所以需要在 C Windows System32下才能找到该命令 是执行该命令的意思 net start mysql 无法启动mysql 根据提示解决了问题 改成 net stop mysql80 net s
  • 多个promise并发执行,如果某个promise失败,则尝试重新执行该promise一次,如果还是失败则提示错误

    思路 可以使用 Promise all 和Promise catch 结合的方式来实现多个promise的并发执行 并在某个promise失败时尝试重新执行 首先 将所有的promise放入数组中 并使用Promise all 来同时执行这