深入理解JS中的Promise.race控制并发量

标题:深入理解JS中的Promise.race控制并发量

简介

JavaScript中的Promise是一种处理异步操作的方式,而Promise.race方法则是Promise对象上的一种方法,它与其他方法不同的是,只要其中的一个Promise状态被改变,Promise.race的状态就会被改变。这个方法通常用来控制异步操作的并发数,即同时进行的异步操作数量。

代码示例1:使用Promise.race限制并发请求

// 定义一个限制并发数量的函数limitRun,参数urls为请求地址数组,max为最大并发数
function limitRun(urls, max) {
  const results = []; //存放所有请求返回结果的数组
  const requestArr = urls.map(url => {
    return fetch(url).then(res => res.json()).then(data => {
      results.push(data); //将结果存入results数组
      console.log(`成功请求${url}所需时间:${Date.now() - start}ms`);
    });
  });

  const start = Date.now(); //开始时间
  const requestTasks = []; //存放所有请求任务的数组
  let pIndex = 0; //正在执行请求的下标

  function addTask() {
    if (pIndex >= urls.length) return; //所有请求任务都已开始,则不再添加

    const curP = Promise.resolve().then(() => {
      return requestArr[pIndex];
    });
    requestTasks.push(curP); //将当前请求任务存入requestTasks数组
    pIndex++; //将正在执行请求的下标移至下一个请求
    curP.then(addTask); //将当前请求执行完毕后再递归添加下一个请求
  }

  while(pIndex < max) { //开始限制并发数
    addTask();
  }

  return Promise.race(requestTasks).then(() => {
    return results; //所有请求执行完毕后返回结果数组
  });
}

const urls = [url1, url2, url3, url4, url5]; //请求地址数组
const max = 3; //最大并发数
limitRun(urls, max).then(results => {
  console.log(`所有请求执行完毕,共耗时${Date.now() - start}ms,请求结果为:`, results);
}).catch(err => {
  console.error(`请求出错:`, err);
});

上述代码中,我们定义了一个函数limitRun,用于限制异步操作的并发数。其中,urls为所有请求地址组成的数组,max为最大并发数。

在函数内部,我们首先创建一个results数组,用于存放所有请求返回的结果,在后续将结果存入数组。然后,我们通过map方法遍历urls数组,将每个请求地址转换成一个Promise请求,并将请求的结果存入results数组中。

之后,我们创建一个requestTasks数组,用于存放所有请求任务,并在while循环中,限制并发数。具体实现方式是,我们用pIndex变量保存正在执行请求的下标(初始值为0),用addTask函数递归添加请求任务,使用Promise.resolve().then方法返回一个Promise请求,并将该请求存入requestTasks数组中。而在递归过程中,我们通过curP.then(addTask)在当前请求执行完毕后继续递归添加下一个请求。

最后,通过Promise.race调用requestTasks数组,只要其中有一个请求任务被执行完毕,就会结束所有任务的执行,然后返回results数组,这个数组存放了所有请求的返回结果。

代码示例2:使用Promise.race实现超时限制

function timeoutPromise(ms) { //返回一个延时Promise对象
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(`请求超时,限制${ms}ms`);
    }, ms);
  });
}

function makeRequest(url, timeout = 3000) { //接收请求地址和超时时间
  return Promise.race([
    fetch(url).then(res => res.json()),
    timeoutPromise(timeout)
  ]);
}

const url = 'https://jsonplaceholder.typicode.com/posts/1'; //请求地址
makeRequest(url, 2000).then(data => {
  console.log(`请求成功,结果为:`, data);
}).catch(err => {
  console.error(`请求出错:`, err);
});

在上述代码中,我们定义了一个timeoutPromise函数,接收一个延时时间ms作为参数,返回一个在ms毫秒后reject的Promise。然后,我们又定义了一个makeRequest函数,接收一个请求地址url和超时时间timeout(默认为3000ms)作为参数,返回一个Promise.race方法调用的结果,该方法接收一个数组,包含fetch请求和timeoutPromise。

当然,如果在timeout时间内fetch请求未能返回结果,timeoutPromise就会先返回reject的结果,结束请求的执行。

总结

Promise.race方法在控制并发量和实现超时限制等场景中非常实用。通过掌握Promise.race的使用,我们可以更好地利用Promise对象处理异步操作。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解JS中的Promise.race控制并发量 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • C#(asp.net)多线程用法示例(可用于同时处理多个任务)

    下面是C#(asp.net)多线程用法示例的完整攻略。 一、为什么需要用到多线程 在编写程序并处理任务时,通常会遇到需要同时处理多个任务的情况,如果使用单线程去处理这些任务,由于任务之间的相互制约和耗时不同,在某个任务没有完成时,程序就会被阻塞,导致程序运行速度慢,用户体验不佳。而多线程则可以让这些任务同时执行,提高程序的执行效率和响应速度。 二、如何使用多…

    多线程 2023年5月17日
    00
  • 简单谈谈Java 中的线程的几种状态

    当Java程序启动时,JVM会为主线程分配一个特殊的栈来执行代码。同时,程序可以创建若干个子线程以支持并发执行相应的任务。线程在执行过程中,可以出现以下几种状态: 新建状态(New) 当线程对象创建以后,该线程处于新建状态。此时线程对象已经在内存中了,但是还没有分配系统资源,没有被CPU选中去执行,也没有开始执行线程中的代码。因此,新建状态的线程在内存中的状…

    多线程 2023年5月16日
    00
  • C++11 并发指南之多线程初探

    C++11 并发指南之多线程初探 什么是多线程 多线程是指在一个进程中运行的多个不同执行流程,每个执行流程叫做一个线程。多线程可以使程序并行执行,提高程序效率。 为什么要使用多线程 在单线程程序中,程序按照顺序执行,如果程序中出现了耗时的操作,程序就会变得非常慢。使用多线程可以使程序中的耗时操作在不同的线程中执行,从而提高程序的执行效率。另外,多线程也可以使…

    多线程 2023年5月16日
    00
  • Java并发编程中使用Executors类创建和管理线程的用法

    一、介绍 在Java并发编程中,线程池是一种重要的技术。通过线程池执行任务可以大大减少资源的开销,提高程序的性能,避免线程过多导致系统资源耗尽的情况。而Executors类就是Java提供的一个专门用于创建和管理线程池的工具类。 二、使用步骤 创建线程池 创建线程池的方式有多种,其中Executors类提供了丰富的静态方法来创建不同类型的线程池。比较常用的是…

    多线程 2023年5月16日
    00
  • C#多线程系列之线程完成数

    C#多线程系列之线程完成数 简介 本文将介绍如何使用C#来获取多线程环境下的线程完成数,以方便监控和调试多线程应用程序,降低程序的复杂度,并提高程序的性能。 获取线程完成数的方法 在C#中,可以使用ManualResetEvent类来实现线程完成数的获取。该类提供的Reset()、WaitOne()、Set()方法可以方便地实现线程的启动、阻塞和唤醒。 具体…

    多线程 2023年5月17日
    00
  • C++ 多线程之互斥量(mutex)详解

    C++ 多线程之互斥量(mutex)详解 什么是互斥量? 在C++中,当多个线程同时访问共享资源时,可能会发生数据冲突或数据竞争的问题,导致程序出错。互斥量就是一种保持互斥、防止数据冲突的机制。在使用互斥量时,只有获取了互斥量的线程才能访问被保护的共享资源,其他线程必须等待。当获取互斥量的线程访问结束并释放互斥量后,其他线程才能继续获取互斥量并访问共享资源。…

    多线程 2023年5月17日
    00
  • java多线程中的volatile和synchronized用法分析

    我来详细讲解关于“java多线程中的volatile和synchronized用法分析”的完整攻略。 1. volatile的用法分析 1.1 volatile的概念 volatile是java多线程并发编程中的关键字,可以保证多线程之间可以正确地处理变量的可见性问题,即当一个变量被volatile修饰后,在某个线程中修改该变量值后,修改后的新值立即被写入主…

    多线程 2023年5月17日
    00
  • 整理总结Java多线程程序编写的要点

    整理总结Java多线程程序编写的要点攻略 Java作为一门强大的编程语言,对于多线程编程也有很好的支持。在Java中,多线程的编写需要关注一些关键要点,才能保证程序的可靠性、性能和可维护性。 1. 线程创建 Java中有两种方式来实现线程的创建:继承Thread类、实现Runnable接口。通常使用后者方法实现更为常见,原因是Java中不允许多重继承。继承T…

    多线程 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部