返回顶部
首页 > 资讯 > 前端开发 > JavaScript >一文详解如何有效的处理Promise并发
  • 772
分享到

一文详解如何有效的处理Promise并发

有效处理Promise并发Promise并发 2023-05-16 15:05:12 772人浏览 泡泡鱼
摘要

目录前言Promise.all如何实现如何处理报错Promise.allSettled如何实现最后两个技巧Promise.racePromise.any总结前言 如上图所示的代码,

前言

如上图所示的代码,相信大家在平时的开发中肯定用到不少,我们可以进行优化,使得只用短短一半的时间就可以完成。 在上面的函数中,我们等待用户信息请求完成后再请求详情信息。但这两个函数之间并没有任何关联,所以我们可以同时触发两个请求,并同时等待完成。那么,我们有多少种方式来实现呢?你真的可以处理好Promise并发么?接下来,我们进入正题。

Promise.all

如何实现

Promise.all 大家应该是比较熟悉的,Promise.all方法接收一个promiseiterable类型,如果所有传入的promise都变成完成状态,Promise.all返回的Promise异步的变为完成。如果传入的promise中有一个失败(rejected),Promise.all将失败的结果给失败状态的回调函数,而不管其他promise是否完成。 我们可以如下实现刚才的代码

async function init() {
  const [user, info] = await Promise.all([
    getUser(),
    getInfo()
  ])
  console.log('init', user, info)
}

现在这种方式,如果我们之前每个请求都需要1秒,一共需要2秒,那么现在两个同时执行只需要1秒就完成了!但是这样也有一个问题:我们并没有考虑报错问题。你可能会认为,这个很简单,把代码放在一个try...cahtch中不就可以了,就像这样:

async function init() {
  try {
    const [user, info] = await Promise.all([
      getUser(),
      getInfo()
    ])
    console.log('init ==== ', user, info)
  } catch(err) {
    console.log('err', err);
  }
}

但是,这样的话会有一个问题,就像这样:

function getUser() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject('user reject')
    }, 500);
  })
}
function getInfo() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject('info reject')
    }, 1000);
  })
}
// 输出 err user reject

由于getUser优先完成并出现错误,此时触发了catch,而当getInfo再次完成并出现错误时,将不会触发catch。因为catch代码已经运行,函数已经完成。 那么,要怎么做呢?接下来,我们就讲讲应该如何处理报错问题。

如何处理报错

解决方式是,给Promise.all中的每个函数加上catch,如下:

function handle(err) {
  console.log('err', err)
}
function onReject(err) {
  handle(err);
  return new Error(err);
}
async function init() {
  const [user, info] = await Promise.all([
    getUser().catch(onReject),
    getInfo().catch(onReject)
  ])
  console.log('init', user instanceof Error, info instanceof Error) // init true true
}

这样,我们在onReject函数中处理错误,并返回这个错误。所以现在我们生成的userinfo要么是Error要么是我们期望的效果,而Error我们可以用instanceof检查它。

Promise.allSettled

解决并发我们还可以使用 Promise.allSettled ,我们会得到一个包含每个Promise结果的值或错误信息。

如何实现

接下来,我们来使用一下,代码如下:

async function init() {
  const [userStatus, infoStatus] = await Promise.allSettled([
    getUser(),
    getInfo()
  ])
  console.log('info', userStatus, infoStatus)
}

现在,我们可以得到这样的数据:

结果对象有3个属性:

  • status: fulfilledrejected
  • value: 仅在statusfulfilled时出现,为Promiseresolve返回的值
  • reason: 仅在statusrejected时出现,为Promisereject时返回的值

因此,我们可以读取到每个Promise的状态,并单独处理每个错误而不会遗漏任何的信息。

最后两个技巧

Promise.race

Promise.race方法可接受一个可迭代的promise返回一个promise,一旦迭代器中某个promise解决或拒绝,返回的promise就会resolvereject

我们可以这样实现一个简单的超时功能,代码如下:

function getUser() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('user resolve')
    }, 5100);
  })
}
async function init() {
  // Race to see which Promise completes first
  const racePromise = Promise.race([
    getUser(),
    new Promise((resolve, reject) =>
      // Time out after 5 seconds
      setTimeout(() => reject(new Error('Timeout')), 5000)
    )
  ])
  try {
    const result = await racePromise
    console.log('result', result)
  } catch (err) {
    console.log('err', err)
    // Timed out!
  }
}

注意,通常情况下,如果有超时,那么你需要尽量的取消未完成的待处理任务。

另外,最好还是处理所有promisereject

const racePromise = Promise.race([
    getUser().catch(onReject),
    // xxx
  ])

Promise.any

Promise.any 等待任何一个promise成功则为成功,只有全部的promise都被reject,才会返回reject。通常我们可以使用Promise.any来实现,当一个promise先完成后,取消其他的promise,不过要注意的是,我们并不总是同时要处理多个数据,只是因为我们可以做到,所以要谨慎的使用它。

通常,我们不想出现未被处理的reject,所以,我们应该这样写:

const anyPromise = Promise.any([
    getUser().catch(onReject),
    getInfo().catch(onReject)
])

总结

前面我们已经介绍了在使用promise处理并发问题时,应该如何的处理promisereject。但是也需要注意:过度的并发会导致网络抖动、磁盘抖动或其他问题,虽然可以,但并不是一定要这样做,有时使用async await也可以使代码更容易理解和维护,所以,在使用之前我们更需要考虑是否需要。

  • 参考文章:www.builder.io/blog/promis…

以上就是一文详解如何有效的处理Promise并发的详细内容,更多关于有效处理Promise并发的资料请关注编程网其它相关文章!

--结束END--

本文标题: 一文详解如何有效的处理Promise并发

本文链接: https://lsjlt.com/news/210184.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 一文详解如何有效的处理Promise并发
    目录前言Promise.all如何实现如何处理报错Promise.allSettled如何实现最后两个技巧Promise.racePromise.any总结前言 如上图所示的代码,...
    99+
    2023-05-16
    有效处理Promise并发 Promise并发
  • Java并发:如何处理多个文件的并发读写?
    Java是一门面向对象的编程语言,以其强大的并发处理能力而著称。在实际开发中,我们经常会遇到需要同时读写多个文件的情况。在这篇文章中,我们将探讨如何使用Java的并发机制来处理多个文件的并发读写问题。 一、Java的并发机制 Java的并发...
    99+
    2023-10-17
    并发 响应 文件
  • 一文详解如何使用Golang处理文件
    目录1. 创建文件与查看状态2. 重命名与移动3. 删除与截断4. 读写文件5. 权限控制6. 文件操作的常见场景6.1 读取配置文件6.2 记录日志6.3 备份文件7. 总结Gol...
    99+
    2023-05-17
    Golang处理文件 Golang文件处理
  • 如何使用Redis锁处理并发问题详解
    前言 上周“被”上线了一个紧急项目,周五下班接到需求,周一开始思考解决方案,周三开发完成,周四走流程上线,也算是面向领导编程了。之前的项目里面由于是自运维,然后大多数又都赶时间,所以在处理定时任务上面基本都...
    99+
    2024-04-02
  • PHP并发编程中,如何有效处理文件和日志的读写操作?
    在PHP并发编程中,文件和日志的读写操作是非常常见的。然而,它们的处理方式会对系统性能产生很大的影响。本文将介绍如何在PHP并发编程中有效处理文件和日志的读写操作。 文件读写 在PHP中,文件读写是通过文件指针来实现的。我们可以使用fop...
    99+
    2023-06-09
    并发 文件 日志
  • JavaScript中Promise如何处理异步的并行与串行
    这篇“JavaScript中Promise如何处理异步的并行与串行”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“JavaSc...
    99+
    2023-07-04
  • 如何在 ASP 中实现高效的并发处理?
    在 ASP 程序中,高效的并发处理是非常重要的。如果你的程序不能有效地处理多个请求,那么你的用户可能会遇到长时间的等待或者甚至是程序崩溃的情况。本文将介绍如何在 ASP 中实现高效的并发处理。 使用异步编程 异步编程是一种在 ASP ...
    99+
    2023-11-12
    并发 数据类型 编程算法
  • Go语言中的文件API并发处理:如何提高程序效率?
    随着计算机技术的不断发展,越来越多的数据需要被处理。而在处理数据的过程中,文件操作是一个非常重要的环节。然而,文件的读写操作通常都是比较耗时的,而且在单线程情况下很难发挥出计算机的性能优势。因此,在实际应用中,我们需要使用并发技术来提高文...
    99+
    2023-11-02
    并发 文件 api
  • ASP 实时 开发技术:如何提高并发处理的效率?
    ASP 实时开发技术:如何提高并发处理的效率? 随着互联网应用的不断普及,越来越多的企业和开发者开始关注 ASP 实时开发技术,以提高应用的性能和并发处理的效率。在本文中,我们将介绍如何使用 ASP 实时开发技术来优化并发处理,提高应用的性...
    99+
    2023-07-03
    实时 开发技术 并发
  • 如何在ASP网站中实现高效的并发处理?
    在ASP网站开发中,实现高效的并发处理是一个非常重要的问题。在高并发访问的情况下,如果不合理地处理,网站的性能将会受到严重的影响。本文将会介绍如何在ASP网站中实现高效的并发处理。 一、使用缓存技术 在ASP网站中,缓存技术是实现高效并发处...
    99+
    2023-09-26
    并发 关键字 索引
  • ASP中如何实现高效的同步和并发处理?
    ASP是一种基于服务器端脚本的动态网页技术,广泛应用于网站开发中。在实际应用中,ASP网站往往需要处理大量的并发请求,因此如何实现高效的同步和并发处理成为了ASP网站开发的一个重要问题。本文将介绍ASP中实现高效同步和并发处理的几种方法,...
    99+
    2023-07-07
    同步 并发 编程算法
  • 如何使用 Python 函数实现高效的并发处理?
    Python 是一种高级语言,使用它编写的程序可以在许多领域得到应用。Python 函数的强大之处在于,它可以让我们以一种高效的方式实现并发处理。在本文中,我们将介绍如何使用 Python 函数实现高效的并发处理。 并发处理是一种实现多任务...
    99+
    2023-08-29
    函数 实时 并发
  • 了解 PHP 容器技术,如何高效地处理并发负载?
    PHP是一门非常流行的编程语言,被广泛应用于Web开发。而随着互联网应用规模的不断扩大,如何高效地处理并发负载成为了一个重要的问题。PHP容器技术就是为了解决这个问题而被提出的。本文将介绍PHP容器技术以及如何利用它来高效处理并发负载。 一...
    99+
    2023-10-28
    并发 容器 load
  • 如何利用PHP实现高效打包并处理并发请求?
    PHP是一种流行的脚本语言,广泛应用于Web开发和服务器端编程。在服务器端编程中,PHP通常用于处理并发请求,例如打包和处理多个请求。本文将介绍如何利用PHP实现高效打包并处理并发请求。 一、打包请求 打包请求是指将多个请求合并为一个请求,...
    99+
    2023-07-27
    打包 并发 面试
  • Go语言并发编程:如何在文件API中实现高效处理?
    Go语言是一种支持并发编程的编程语言,拥有强大的并发编程库和工具,可以帮助开发者在处理大规模数据时更加高效。在文件API中,Go语言的并发编程可以帮助我们实现高效的文件读取和写入,提高文件处理效率,降低程序运行时间和资源消耗。 串行文件...
    99+
    2023-11-02
    并发 文件 api
  • 如何在ASP中实现高效的Windows函数并发处理?
    ASP是一种非常流行的Web应用程序开发技术,它可以实现动态Web页面的创建、管理和处理。在ASP中,我们经常会使用一些Windows函数来实现一些高级功能,如文件操作、网络通信等等。但是在处理大量的数据时,我们需要考虑如何实现高效的Wi...
    99+
    2023-10-10
    windows 函数 并发
  • Golang 文件上传中如何处理并发上传?
    并发文件上传涉及对上传请求实施并发限制、使用队列管理上传顺序、处理异常情况等步骤。在 golang 中,可通过以下方式实现:设置并发上限,避免资源耗尽。使用队列管理待处理请求,确保公平性...
    99+
    2024-05-14
    golang 并发上传
  • Go并发与锁的两种方式该如何提效详解
    目录并发不安全的例子互斥锁读写锁小结总结并发安全,就是多个并发体在同一段时间内访问同一个共享数据,共享数据能被正确处理。 很多语言的并发编程很容易在同时修改某个变量的时候,因为操作不...
    99+
    2022-12-27
    golang 并发锁 go控制并发 Go并发
  • Go文件处理:如何有效地管理你的数据?
    数据是我们生活和工作中必不可少的一部分,对于程序员而言,文件处理是日常工作中不可或缺的部分。在Go语言中,我们可以通过各种方式来管理文件和数据。本文将介绍如何使用Go语言来处理文件和数据,以及如何有效地管理你的数据。 一、读取文件 在Go...
    99+
    2023-09-05
    缓存 日志 文件
  • PHP并发编程:如何高效地处理大量请求?
    随着互联网的普及和云计算技术的发展,我们的应用程序面临着越来越多的并发请求。在这种情况下,如何高效地处理大量请求,是每个开发人员需要面对的问题。在PHP编程中,我们可以采用以下几种方式来实现并发处理。 多线程编程 多线程编程是一种常见...
    99+
    2023-07-01
    响应 索引 并发
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作