JavaScript使用Promise实现并发请求数限制

目录
  • 没有Promise的并发请求
  • 使用Promise限制并发请求
  • 使用Promise实现并发请求数限制
  • 总结

没有Promise的并发请求

在Web开发中,我们经常需要发起多个异步请求来获取数据。例如,我们可能需要从服务器获取一些用户信息、文章内容、评论列表等等。如果我们使用的是传统的JavaScript回调函数,可能会写出类似下面这样的代码:

function getUsers(callback) {
  fetch('https://example.com/users', (response) => {
    if (response.status === 200) {
      response.json((data) => {
        callback(data);
      });
    } else {
      console.error('Error fetching users');
    }
  });
}

function getPosts(callback) {
  fetch('https://example.com/posts', (response) => {
    if (response.status === 200) {
      response.json((data) => {
        callback(data);
      });
    } else {
      console.error('Error fetching posts');
    }
  });
}

function getComments(callback) {
  fetch('https://example.com/comments', (response) => {
    if (response.status === 200) {
      response.json((data) => {
        callback(data);
      });
    } else {
      console.error('Error fetching comments');
    }
  });
}

getUsers((users) => {
  console.log(users);
});

getPosts((posts) => {
  console.log(posts);
});

getComments((comments) => {
  console.log(comments);
});

在这个例子中,我们定义了三个函数来获取不同的数据,每个函数都接受一个回调函数作为参数。当响应成功返回时,我们会调用回调函数并将响应数据传递给它。这种方式看起来很简单,但如果我们需要发起更多的请求,代码会变得越来越难以维护。

另外一个问题是,如果我们需要在多个请求都完成后进行处理,我们需要使用一些技巧来确保所有请求都已经完成。例如,我们可以使用计数器来跟踪已完成的请求数,并在所有请求都完成后执行回调函数。这种方式也很容易出错,特别是当请求失败时。

使用Promise限制并发请求

幸运的是,JavaScript中有一个非常有用的工具,可以帮助我们更好地处理异步请求:Promise。使用Promise,我们可以将异步请求看作是一个返回Promise对象的函数,然后使用链式调用来处理请求的结果。

例如,我们可以将上面的代码改写成使用Promise的形式:

function getUsers() {
  return fetch('https://example.com/users').then((response) => {
    if (response.status === 200) {
      return response.json();
    } else {
      throw new Error('Error fetching users');
    }
  });
}

function getPosts() {
  return fetch('https://example.com/posts').then((response) => {
    if (response.status === 200) {
      return response.json();
    } else {
      throw new Error('Error fetching posts');
    }
  });
}

function getComments() {
  return fetch('https://example.com/comments').then((response) => {
    if (response.status === 200) {
      return response.json();
    } else {
      throw new Error('Error fetching comments');
    }
  });
}

Promise.all([getUsers(), getPosts(), getComments()]).then(([users, posts, comments]) => {
  console.log(users);
  console.log(posts);
  console.log(comments);
}).catch((error) => {
  console.error(error);
});

在这个例子中,我们将每个获取数据的函数改写成返回Promise对象的形式。当响应成功返回时,我们会使用then方法来处理响应数据。如果响应失败,我们会使用throw语句抛出一个错误。

然后,我们使用Promise.all函数来等待所有请求完成,并将所有响应数据存储在一个数组中。当所有请求都完成后,我们可以使用解构赋值来获取每个响应数据,并进行处理。如果有任何请求失败,我们可以使用catch方法来处理错误。

这种方式比使用回调函数更加简洁和易于维护,但它仍然有一个问题:如果我们同时发起太多的请求,可能会导致服务器过载或者网络拥塞。因此,我们需要限制并发请求数,以确保我们的应用程序可以正常运行。

使用Promise实现并发请求数限制

在JavaScript中,我们可以使用Promise.all函数来等待所有请求完成。但是,Promise.all函数会等待所有Promise对象都已解析后才返回结果。如果我们同时发起太多的请求,可能会导致浏览器崩溃或者内存溢出。

幸运的是,我们可以使用一些技巧来限制并发请求数。例如,我们可以使用一个计数器来跟踪当前正在进行的请求数,然后在所有请求都完成后执行回调函数。这种方式可以确保我们不会同时发起太多的请求,从而避免服务器过载或者网络拥塞。

以下是一个使用Promise实现并发请求数限制的示例代码:

function limitRequest(urls, limit) {
  let index = 0; // 初始化请求索引为0
  const results = []; // 存储所有请求的响应结果
  const inProgress = []; // 存储当前正在进行的请求

  const executeRequest = (url) => { // 定义执行请求的函数
    const promise = fetch(url).then((response) => response.json()); // 发起请求并返回一个Promise对象
    inProgress.push(promise); // 将Promise对象添加到inProgress数组中
    const removeInProgress = () => { // 定义一个函数,用于将Promise对象从inProgress数组中删除
      const i = inProgress.indexOf(promise);
      if (i !== -1) {
        inProgress.splice(i, 1);
      }
    };
    promise.then((result) => { // 请求成功的回调函数
      removeInProgress(); // 将Promise对象从inProgress数组中删除
      results.push(result); // 将响应结果存储到results数组中
      if (index < urls.length) { // 如果还有未完成的请求,继续执行下一个请求
        executeRequest(urls[index++]);
      }
    }).catch((error) => { // 请求失败的回调函数
      removeInProgress(); // 将Promise对象从inProgress数组中删除
      console.error(error); // 打印错误信息
    });
  };

  while (index < limit && index < urls.length) { // 启动最初的一批请求
    executeRequest(urls[index++]);
  }

  return Promise.all(inProgress).then(() => results); // 等待所有请求完成,并返回results数组的Promise对象
}

在此示例中,我们定义了一个limitRequest函数,用于限制并发请求数,并将所有请求的响应结果存储在results数组中。我们使用executeRequest函数来执行请求,并跟踪当前正在进行的请求。我们使用while循环来启动最初的一批请求,并在请求完成后继续执行后续请求,直到所有请求都完成。最后,我们使用Promise.all函数来等待所有请求完成,并返回results数组。

总结

在本文中,我们介绍了如何使用Promise来处理异步请求,并使用Promise.all函数来等待所有请求完成。我们还讨论了如何限制并发请求数,以确保我们的应用程序可以正常运行。使用Promise,我们可以写出更加简洁、可维护的代码,并且可以更好地处理异步请求。

到此这篇关于JavaScript使用Promise实现并发请求数限制的文章就介绍到这了,更多相关JavaScript Promise并发请求限制内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • js Promise并发控制数量的方法

    目录 问题 背景 思路 & 实现 问题 要求写一个方法控制 Promise 并发数量,如下: promiseConcurrencyLimit(limit, array, iteratorFn) limit 是同一时间执行的 promise 数量,array 是参数数组,iteratorFn 每个 promise 中执行的异步操作. 背景 开发中需要在多个promise处理完成后执行后置逻辑,通常使用Promise.all: Primise.all([p1, p2, p3]).then((res)

  • JavaScript如何利用Promise控制并发请求个数

    一.场景 假设现在有这么一种场景:现有 30 个异步请求需要发送,但由于某些原因,我们必须将同一时刻并发请求数量控制在 5 个以内,同时还要尽可能快速的拿到响应结果. 如图所示: 上图这样的排队和并发请求的场景基本类似,窗口只有三个,人超过三个之后,后面的人只能排队了. 二.串行和并行 串行:一个异步请求完了之后在进行下一个请求 并行:多个异步请求同时进行 串行举例: var p = function () { return new Promise(function (resolve, reje

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

    目录 开篇 一.Promise.race 二.并发效果展示 三.代码 总结与思考 开篇 比如在开发中会进行一系列的网络请求,但是有些情况需要控制一下网络请求请并发量.这里简单的用 Promise.race 及 await 的特性来理解一下,如何对任务的并发量进行控制. 一.Promise.race Promise.race 作用就是将多个异步任务包裹起来,当有一个完成的话,那么就会触发 then 事件.除了这个不错的特性方法外,await 这个关键字也比较有用,可以这样理解,await 后面的代

  • JavaScript使用Promise实现并发请求数限制

    目录 没有Promise的并发请求 使用Promise限制并发请求 使用Promise实现并发请求数限制 总结 没有Promise的并发请求 在Web开发中,我们经常需要发起多个异步请求来获取数据.例如,我们可能需要从服务器获取一些用户信息.文章内容.评论列表等等.如果我们使用的是传统的JavaScript回调函数,可能会写出类似下面这样的代码: function getUsers(callback) { fetch('https://example.com/users', (response)

  • nginx限制并发连接请求数的方法

    简介 限制并发连接数的模块为:http_limit_conn_module,地址:http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html 限制并发请求数的模块为:http_limit_req_module,地址:http://nginx.org/en/docs/http/ngx_http_limit_req_module.html 这两个模块都是默认编译进Nginx中的. 限制并发连接数 示例配置: http { limit_c

  • 在vue项目中promise解决回调地狱和并发请求的问题

    场景需求: 需要同时请求5个接口 都请求成功后执行下一步操作 解决方法: 定义一个变量i=5,请求成功一个接口,让i–,直到i=0时执行下一个操作,否则不执行 axios.all 并发请求,.then(axios.spread(function(callback1, callback2)){}) promise.all 并发请求,.then(function([callback1, callback2]){}) 1.回调地狱: 函数作为参数层层嵌套 代替的为.then的链式操作 2.promis

  • JavaScript/TypeScript 实现并发请求控制的示例代码

    场景 假设有 10 个请求,但是最大的并发数目是 5 个,并且要求拿到请求结果,这样就是一个简单的并发请求控制 模拟 利用 setTimeout 实行简单模仿一个请求 let startTime = Date.now(); const timeout = (timeout: number, ret: number) => { return (idx?: any) => new Promise((resolve) => { setTimeout(() => { const compa

  • JavaScript使用promise处理多重复请求

    一.为什么要写这个文章? 处理重复请求的文章想必大家也看过了很多,大多数都是分为在response返回之前发现重复请求就return掉的和使用节流/防抖来间接规避用户频繁操作两种版本的.最近在使用的过程的中,发现这两个版本在某些场景下还是有些局限性. 二.问题场景 如图,我这个h5的页面,顶部和底部都要显示这个名片组件.这些名片的信息是通过一个接口来获取的,当这个组件在当前页面被初始化时,就会发生两次重复的请求. 这时会面临几个抉择: 1. 不对重复请求做任何处理. 缺点1:造成不必要的资源浪费

  • Vue Promise的axios请求封装详解

    现在应该大部分公司都是前后端分离了.so,数据请求的封装还是必须的. 为了实现向ios中block封装请求的异步的效果,我采用JavaScript中promise这个对象. var p1 = New promise((resolve,reject)=>{ var timeOut = Math.random() * 2; log('set timeout to: ' + timeOut + ' seconds.'); setTimeout(function () { if (timeOut <

  • 字节跳动面试之如何用JS实现Ajax并发请求控制

    前言 讲真的,最近也很迷茫.关于技术.关于生活吧.也找了很多在大厂的朋友去聊,想需求一些后期发展的思路.这其中也聊到了面试,聊到了招聘中会给面试者出的一些题目.我正好也好久没面试了,就从中选了几道.最近也会陆续出一系列关于一些面试问题的解析. 今天这道是字节跳动的: 实现一个批量请求函数 multiRequest(urls, maxNum),要求如下: • 要求最大并发数 maxNum • 每当有一个请求返回,就留下一个空位,可以增加新的请求 • 所有请求完成后,结果按照 urls 里面的顺序依

  • 利用js实现Ajax并发请求限制请求数量的示例代码

    出现问题描述:当不确定异步请求个数时,为防止当一瞬间发生上百个http请求时,导致堆积了无数调用栈进而导致内存溢出问题. 要求:将同一时刻并发请求数量控制在3个以内,同时还要尽可能快速的拿到响应的结果. 同面试问题: 实现一个批量请求函数 multiRequest(urls, maxNum),要求如下: 要求最大并发数 maxNum 每当有一个请求返回,就留下一个空位,可以增加新的请求 所有请求完成后,结果按照 urls 里面的顺序依次打出 1.基于Promise.all实现Ajax的串行和并行

  • 如何基于JS实现Ajax并发请求的控制详解

    目录 前言 Ajax的串行与并行 Ajax的并发请求控制的两大解决方案 基于Promise递归实现 基于Class实现 代码展示 总结 前言 最近看到一个面试题,当然了,就是这篇文章的标题,Ajax的并发请求的控制,感觉挺有意思的,在社区看了下,应该是字节的面试题,也挺多大佬对这个进行了总结,都看了下,于是自己也想试着总结下,代码文末会全部贴出,如有不足,请指出! Ajax的串行与并行 串行:一般业务需求是下个接口需要用到上个接口的返回的数据,前端常用的请求库是Axios,本身就是基于Promi

随机推荐