Tips to avoid multiple HTTP requests being sent simultaneously

I have a collection of objects that requires triggering asynchronous requests for each object. However, I want to limit the number of simultaneous requests running at once. Additionally, it would be beneficial to have a single point of synchronization after all requests are complete to execute additional code.

I have explored various suggestions from:

Limit number of requests at a time with RxJS

How to limit the concurrency of flatMap?

Fire async request in parallel but get result in order using rxjs

and more... I even attempted to create my own operators.

However, either the solutions provided do not align with my specific requirements or I am struggling to integrate them seamlessly into my existing codebase.

This is the current state of my implementation:

for (const obj of objects) {
  this.myService.updateObject(obj).subscribe(value => {
    this.anotherService.set(obj);
  });
}

EDIT 1: I believe progress is being made! Utilizing the insights from Julius and pschild, I have managed to control the request concurrency. However, only the first batch of 4 requests is triggered while subsequent batches remain inactive. Here's the updated snippet:

const concurrentRequests = 4;
from(objects)
  .pipe(
    mergeMap(obj => this.myService.updateObject(obj), concurrentRequests),
    tap(result => this.anotherService.set(result))
  ).subscribe();

Is there an issue with the way I'm handling the subscribe() method?

By the way: The use of mergeMap with the resultSelector parameter has been deprecated, hence why I omitted it. Also, the reference to obj within the mergeMap function is not accessible in the tap, necessitating the use of the parameter passed to tap.

EDIT 2:

Ensure that your observers complete! (This lesson cost me an entire day)

Answer №1

If you want to restrict the number of simultaneous inner subscriptions, you can utilize the third parameter of mergeMap. Additionally, you can make use of finalize to run a task after all requests have been completed:

const maxConcurrentRequests = 5;
from(objects)
    .pipe(
        mergeMap(obj => this.myService.updateObject(obj), maxConcurrentRequests),
        tap(res => this.anotherService.set(res))),
        finalize(() => console.log('Sequence complete'))
    );

Check out the demonstration on Stackblitz.

Answer №2

Using the objects array, this code snippet filters them into batches of 10 and then performs an asynchronous update operation on each object using myService. After updating each object, it also calls another service method to set additional values. Finally, it logs a message indicating that all requests have been completed.

This code is provided as an example and has not been tested. Feel free to ask for clarification or report any errors.

Answer №3

I encountered a similar problem in the past while attempting to load multiple images from a server. To address this issue, I had to send HTTP requests sequentially, ultimately achieving my desired outcome by utilizing awaited promises. Below is a snippet of the code I used:

async ngOnInit() {
    for (const number of this.numbers) {
      await new Promise(resolve => {
        this.http.get(`https://jsonplaceholder.typicode.com/todos/${number}`).subscribe(
          data => {
            this.responses.push(data);
            console.log(data);
            resolve();
          }
        );
      });
    }
  }

The key concept here is to resolve the promise upon receiving the response. This approach allows for the implementation of custom logic to execute certain actions once all requests have been completed.

You can view the live demo on StackBlitz. Make sure to check the console for real-time updates! :)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What could be causing the npm mysql module to malfunction when trying to initiate the 'connect()' function in a separate .js file?

When I call require('mysql') and use the function connect() everything works fine. However, if I try to call the 'connect()' function in another file, it throws an error saying connection.connect is not a function... Any suggestions on ...

Issue encountered: Unforeseen command: POST karma

Whenever I try to run my test cases, I encounter the following error message: Error: Unexpected request: POST data/json/api.json it("should $watch value", function(){ var request = '/data/json/api.json'; $httpBackend.expectPOST(reque ...

Creating a csproj file for an existing project in Angular: A step-by-step guide

I recently utilized the Angular CLI (version 12) to initiate my Angular project, but I noticed that the csproj file is missing. Is there a method to generate the csproj without compromising any of the existing files? Any help would be greatly appreciated ...

I keep receiving multiple header errors from ExpressJS even though I am positive that I am only sending a single header

Can someone please help with the issue I'm facing in the code below: router.put("/:_id", async (req: Request, res: Response) => { try { // Create the updated artist variable const artist: IArtist = req.body; const updatedArt ...

Creating a robust web application using Laravel API, Sanctum, Angular, and SSO with SAML authentication. Learn how to construct a sophisticated Laravel 7/8 backend API integrated with an Angular 11 front-end and

I am looking to transition my authentication system from laravel api + angular with sanctum to SAML authentication. After some research, I've found that using a laravel plugin like laravel-saml2 or laravel-saml2 would be necessary. (Interestingly eno ...

Storing an array within an AngularJS service for better performance

As someone who is relatively new to AngularJS, I am still in the process of understanding how to utilize services for fetching data in my application. My aim here is to find a method to store the output of a $http.get() call that returns a JSON array. In ...

Update the ngView content on the fly

My project requires dynamic routes to be generated when specific URLs are requested in order to customize the view and display corresponding data uniformly. While adding manual routes with the same templateUrl and controller would have made this task simpl ...

Embedding a string within an image source attribute in VueJS

My goal is to extract the name of a job department as data for a Vue component, convert it to lowercase, and then use it to dynamically render the correct image based on the department's name. The images are named after the departments. The current c ...

Protractor's modal dialogue displays numerous outcomes when accessing ng-repeater elements

Trying to click on an element located within a repeater has presented some challenges. The issue arises from the fact that it is a modal dialog and returns multiple elements for the repeater. Each page in our application functions as a modal dialog, leadin ...

Watching a live video stream in real-time using WebRTC with React

Here is the HTML code <video ref={videos} autoPlay ></video> <Button onClick={() => navigator.mediaDevices.getUserMedia({audio: true, video: true}).then((mediaStream) => { videos.srcObject = mediaStream; videos.onloadedmetad ...

Issues with setting default values for controls in Angular's reactive forms

I need help with displaying a preselected option on my dropdown list. I have set the value to preSelectedLegalType in the ngOnInit function, but for some reason it is not getting displayed. How can I make sure this value is displayed? The TypeScript file ...

Testing the Viewchild directive in Angular 2

I'm facing an issue with a component setup like this: export class ParentComponent implements OnInit, OnDestroy { @ViewChild(ChildComponent) childComponent: ChildComponent; } In this setup, the ParentComponent is using childComponent to make a ...

Resetting the selected value in an Angular2 select element after the user makes a change

I have a dropdown menu which the user can select an option from. Initially it has a default value and when the user makes a new selection, I need to ask for confirmation by showing a message "are you sure?". If the answer is NO, then I should revert back t ...

Utilizing JavaScript and jQuery libraries in conjunction with periods

I am a bit puzzled about when to include the period before referencing class names. For instance, in this code snippet, why is a period included before the first use of the 'active-slide' class but not for the other two instances? var primary = ...

Testing the branch count of optional chaining in Typescript

I am struggling to grasp the concept of branch coverage, especially when it involves optional chaining in TypeScript. Below is my code snippet: type testingType = { b?: { a?: number }; }; export function example(input: testingType) { return input. ...

In the world of React in Meteor, the command event.preventDefault() doesn't seem

I have encountered an issue with my application development. I am utilizing a submit form in Meteor with React, and although I am using event.preventDefault(), the page continues to reload every time the submit button is clicked. Following a brief delay, i ...

Examining the ngOnChanges function of a child component within an Angular unit test

I am currently working on writing unit tests for an Angular child component that uses ngOnChanges with @Input. I found a helpful approach in this article: here Below is a snippet of my code. import { Component, NO_ERRORS_SCHEMA, SimpleChange } from ' ...

Unable to display canvas background image upon webpage loading

Currently working on a JavaScript project to create a captcha display on a canvas. The issue I'm facing is that the background image does not load when the page initially opens. However, upon hitting the refresh button, it functions as intended. Here& ...

Steps to hide a div with jQuery when a user clicks outside of a link or the div itself:1. Create a click event

Here's a simple question - I have a link that when clicked, displays a div. If the user clicks away from the link, the div is hidden, which is good. However, I don't want the div to be hidden if the user clicks on it. I only want the div to disap ...

Is there a way to alter the CSS padding class for collapsed elements?

I've created a navbar by following Bootstrap's tutorial, but I'm facing an issue with the padding. I used the Bootstrap class "pe-5" to add padding to a form within the navbar so that it aligns to the right with some space from the screen ed ...