You are given an info-graphic component where you have to batch call APIs in sequence. Let’s say you have 20 APIs to call, batch call 5 APIs together, and the next 5 after the previous one is done, and so on. The first call will take after a delay of 5 seconds and once all the APIs are executed, reset and start from the beginning.
Example
Input: // API calls [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] // [1, 2, 3, 4, 5] // first call after 5 seconds // [6, 7, 8, 9, 10] // second call // [11, 12, 13, 14, 15] // third call // [16, 17, 18, 19, 20] // fourth call
We will use a dummy promise that will resolve after 1 second to mimic the API call.
- Then break the array of promises in chunk of 5.
- Use a state to track the indexes of these subarrays, inside the
useEffect
hook, check if the current index is first then make the call after the 5 seconds, and once all APIs are executed update the state and increment the index. If the index is greater than the subarray size then reset it. - After the index will update
useEffect
hook will be invoked and the subsequent calls will be made, thus all the APIs will be executed recursively. - To make the API calls we will use a helper function that will execute all the promises in parallel and increment the index after the operation.
import { useState, useEffect } from "react"; // helper function to create promise task // that resolves randomly after some time const asyncTask = function (i) { return new Promise((resolve, reject) => { setTimeout(() => resolve(`Completing ${i}`), 1000); }); }; // helper function to create sub arrays of given size const chop = (arr, size = arr.length) => { //temp array const temp = [...arr]; //output const output = []; let i = 0; //iterate the array while (i < temp.length) { //slice the sub-array of given size //and push them in output array output.push(temp.slice(i, i + size)); i = i + size; } return output; }; const Example = () => { // array of promises // 20 const promises = [ asyncTask(1), asyncTask(2), asyncTask(3), asyncTask(4), asyncTask(5), asyncTask(6), asyncTask(7), asyncTask(8), asyncTask(9), asyncTask(10), asyncTask(11), asyncTask(12), asyncTask(13), asyncTask(14), asyncTask(15), asyncTask(16), asyncTask(17), asyncTask(18), asyncTask(19), asyncTask(20), ]; // sub array of promises of size 5 // 4 sub arrays in total const subArrays = chop(promises, 5); // to track the indexes of subarrays const [index, setIndex] = useState(0); // helper function to perform the asyncoperations const asyncOperations = async (promises) => { try { // execute all the promises of sub-array togther const resp = await Promise.all(promises); // print the output of the current sub array console.log(index, resp); } catch (e) { console.log(e); } finally { // update the index after the operation setIndex(index < subArrays.length - 1 ? index + 1 : 0); } }; useEffect(() => { // run first promise after 5 second if (index === 0) { setTimeout(() => { asyncOperations(subArrays[index]); }, 5000); } // and the remaining promises after the previous one is done else { asyncOperations(subArrays[index]); } }, [index]); return <></>; }; export default Example;
Output
// each after 5 seconds 0 (5) ['Completing 1', 'Completing 2', 'Completing 3', 'Completing 4', 'Completing 5'] 1 (5) ['Completing 6', 'Completing 7', 'Completing 8', 'Completing 9', 'Completing 10'] 2 (5) ['Completing 11', 'Completing 12', 'Completing 13', 'Completing 14', 'Completing 15'] 3 (5) ['Completing 16', 'Completing 17', 'Completing 18', 'Completing 19', 'Completing 20']