w3resource

Control Concurrent API Requests with JavaScript Throttling Techniques


Simulating a Throttled API:

Write a JavaScript function that ensures only a specified number of asynchronous requests are made simultaneously.

Solution-1: Implementing Throttling Using a Queue

Code:

// Function to simulate an API request
const apiRequest = (id, time) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(`Request ${id} completed in ${time}ms`);
    }, time);
  });
};

// Throttled execution function
const throttledAPI = (requests, maxConcurrent) => {
  const results = [];
  let running = 0;
  let currentIndex = 0;

  return new Promise((resolve) => {
    // Function to process the next request
    const processNext = () => {
      if (currentIndex >= requests.length && running === 0) {
        resolve(results); // Resolve when all requests are processed
        return;
      }

      if (running < maxConcurrent && currentIndex < requests.length) {
        running++; // Increment running count
        const index = currentIndex;
        const request = requests[currentIndex];
        currentIndex++; // Move to the next request

        request().then((result) => {
          results[index] = result; // Store the result
          running--; // Decrement running count
          processNext(); // Trigger the next request
        });
      }
    };

    // Start the initial batch
    for (let i = 0; i < maxConcurrent; i++) {
      processNext();
    }
  });
};

// Create an array of simulated API requests
const requests = [
  () => apiRequest(1, 1000),
  () => apiRequest(2, 500),
  () => apiRequest(3, 1500),
  () => apiRequest(4, 100),
  () => apiRequest(5, 2000),
];

// Run the throttled API with a limit of 2 concurrent requests
throttledAPI(requests, 2).then((results) => {
  console.log("Results:", results); // Logs results in order
});

Output:

"Results:"
["Request 1 completed in 1000ms", "Request 2 completed in 500ms", "Request 3 completed in 1500ms", "Request 4 completed in 100ms", "Request 5 completed in 2000ms"]

Explanation:

  • API Simulation: apiRequest simulates an asynchronous API call.
  • Queue Mechanism: Maintains a queue of pending requests and processes a maximum number (maxConcurrent) concurrently.
  • Sequential Processing: Uses a loop and processNext function to control the flow.
  • Completion: Resolves the results once all requests are processed.

Solution-2: Throttling Using Promise.all

Code:

// Function to simulate an API request
const apiRequest = (id, time) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(`Request ${id} completed in ${time}ms`);
    }, time);
  });
};

// Function to run requests with throttling
const throttledAPI = async (requests, maxConcurrent) => {
  const results = [];
  const executing = new Set();

  for (const request of requests) {
    const promise = request().then((result) => {
      executing.delete(promise); // Remove completed request from executing
      return result;
    });

    executing.add(promise); // Add request to executing
    results.push(promise);

    if (executing.size >= maxConcurrent) {
      await Promise.race(executing); // Wait for one request to finish
    }
  }

  return Promise.all(results); // Wait for all requests to finish
};

// Create an array of simulated API requests
const requests = [
  () => apiRequest(1, 1000),
  () => apiRequest(2, 500),
  () => apiRequest(3, 1500),
  () => apiRequest(4, 100),
  () => apiRequest(5, 2000),
];

// Run the throttled API with a limit of 2 concurrent requests
throttledAPI(requests, 2).then((results) => {
  console.log("Results:", results); // Logs results in order
});

Output:

"Results:"
["Request 1 completed in 1000ms", "Request 2 completed in 500ms"]

Explanation:

  • API Simulation: Same as Solution 1.
  • Promise Set: Tracks active requests using a Set to handle concurrency.
  • Throttling with Promise.race: Waits for one active request to finish before starting the next.
  • Completion: Uses Promise.all to ensure all requests complete.

See the Pen promises-and-async-await-exercise-9 by w3resource (@w3resource) on CodePen.


For more Practice: Solve these Related Problems:

  • Write a JavaScript function that limits the number of concurrent API calls to a fixed threshold using Promises.
  • Write a JavaScript program that simulates a throttled API by queuing requests and processing only a set number at a time.
  • Write a JavaScript function that implements a concurrency control mechanism for asynchronous fetch requests.
  • Write a JavaScript program that simulates API rate limiting by delaying queued requests based on a maximum concurrency limit.

Go to:


PREV : Error Handling in Async/Await.
NEXT : Custom Promise Wrapper.

Improve this sample solution and post your code through Disqus

What is the difficulty level of this exercise?

Test your Programming skills with w3resource's quiz.



Follow us on Facebook and Twitter for latest update.