Steps to develop a countdown timer for every iteration of sending an API request using a specified list

Recently, I encountered a challenge with my JavaScript array that holds 40 items. My goal was to develop a function capable of cycling through each item in the array and initiating an API call based on the current value.

The caveat here is that I needed a 3-second interval between each API call to avoid surpassing the allowable limit of API calls per second.

In my attempt to resolve this issue, I created the following function to fetch a list of properties stored in an array:

const getPropertiesInCity = (properties) => {
  for(i = 0; i < properties.length; i++){
    let property = properties[i]
    setTimeout(() => {
      getPropertyDetails(property.zpid)
    }, 5000)
  }
}

The outcome of running this function resulted in a series of errors followed by successful responses, as indicated below:

Error
Error
Error
...
Have the property
Have the property
Have the property

The errors were a direct result of exceeding the specified time frame for sending requests. The function would pause for 5 seconds before producing all the errors at once, followed by 3 positive responses.

Answer №1

Your approach to scheduling API calls all at once within a 5-second time frame may not effectively space them out as intended. This is because `setTimeout()` function allows for non-blocking execution, causing the entire loop to run immediately without intervals between calls. To address this issue and achieve a delay of 3 seconds between each call, you can adjust the timer value within the loop iteration.

const getPropertiesInCity = (properties) => {
  for(let i = 0; i < properties.length; i++){
    let property = properties[i]
    setTimeout(() => {
      getPropertyDetails(property.zpid)
    }, i * 3000)
  }
}

An alternative technique involves initiating the subsequent iteration with a set timeout duration directly within the loop:

const getPropertiesInCity - (properties) => {
    let i = 0;
    function run() {
        if (i < properties.length) {
            getPropertiesDetails(properties[i++].zpid);
            // schedule next iteration of the loop
            setTimeout(run, 3000);
        }
    }
    run();
}; 

In scenarios where `getPropertiesDetails()` either returns a promise or requires a completion callback, an effective strategy would be to commence the following iteration after its execution by incorporating a timer for a delayed start rather than triggering it immediately upon invocation.

Answer №2

If you're looking to leverage the power of the iter-ops library (which I happen to have authored), here's a sample code snippet for you:

import {pipeAsync, map, wait, delay} from 'iter-ops';

const properties = [...]; // your list of objects

const i = pipeAsync(
    properties,
    map(p => getPropertyDetails(p.zpid)), // transforming into requests
    wait(), // waiting for request completion
    delay(5000) // adding a 5-second delay
); //=> AsyncIterable

// handling any errors during iteration:
i.catch(err => {
    console.log('CAUGHT:', err);
});

(async function () {
    for await (const a of i) {
        console.log(a); // outputting the results of getPropertyDetails
    }
})();

This example not only provides you with the outcomes of each getPropertyDetails call but also centralizes error management.

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

Align pictures in the middle of two divisions within a segment

This is the current code: HTML: <section class="sponsorSection"> <div class="sponsorImageRow"> <div class="sponsorImageColumn"> <img src="img/kvadrat_logo.png" class="sponsorpicture1"/> </div& ...

Unit testing Node.js middleware specific to sessions

I am currently working on writing a unit test for a middleware that depends on persistent sessions in connect (specifically connect-mongo). My goal is to create a fake session, but I am encountering some challenges in figuring out how to do so. In my bro ...

How can I attach events to newly generated elements without using jQuery?

If I want to dynamically add a form to my webpage (through AJAX or other JavaScript methods), how can I attach event listeners to these elements before they actually exist on the page? When using jQuery, it's simple to bind the events to a parent ele ...

React developers are struggling with parsing XML data with ReactDOM

While working on my React application, I encountered an issue with parsing an XML file. When I hard code the XML data in my file listener, I get the correct answer (2): const raw = `<?xml version="1.0" encoding="ISO-8859-1" ?> <?xml-stylesheet ...

Is there a way to create a unique set of string values using the keys and values from an object that are produced by a function?

I am currently in the process of defining a new type based on an immutable object, like so: const Actions = { 'user.crud': ['user.create', 'user.read', 'user.update', 'user.delete'], } as const type Ac ...

How can you quickly navigate to the top of the page before clicking on a link in the same window/tab?

Could someone assist me with a coding issue I am facing? I would like to be able to go to the top of the page when clicking on a link and have the link open in the same tab. I attempted to implement this functionality using the following code, however, I ...

Vue component is showing undefined when attempting to run app.config

The contents of my main.js file in the app are as follows: import { createApp } from 'vue' import App from './App.vue' import router from './router' const app = createApp(App) const globalProps = app.config.globalProperties ...

When Proxy server Node redirects, Nginx does not receive the custom header

Currently, my NGINX server is directed to a proxy server running on Node. I've set up a redirection to `app/` from Node using `express redirect` and included a custom header with `res.set("X-Custom-Header","XXX");` before the redirect. However, when a ...

Eliminating the spacing between elements to create a seamless design

Currently immersed in the creation of a new website, I am facing an issue with closing the margin gap on the right side of the page. The problem persists despite setting the body's margin to 0px. Any assistance in resolving this issue would be greatly ...

Waiting for the execution of the loop to be completed before proceeding - Typescript (Angular)

There's a code snippet triggered on an HTML page when clicked: public salaryConfirmation() { const matDialogConfig: MatDialogConfig = _.cloneDeep(GajiIdSettings.DIALOG_CONFIG); this.warningNameList = []; for(let i=0; i < this.kelolaDat ...

Cannot find property in type, and the parameter is implicitly of an unspecified type

I've been encountering this issue where I keep getting an error message. I attempted to resolve it by setting "noImplicitAny": false in tsconfig.json, but unfortunately that did not work. As for the 'Property does not exist on type' error, I ...

How come running `npm install <folder>` results in installing different dependencies compared to `npm install lib`?

My current project, project1, relies on <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5221262b3e37367f313d3f223d3c373c262112667c6">[email protected]</a>. When attempting to integrate project2 into project1 as a ...

Guide on making an active link the default setting upon the initial loading of a page with Angular 2

import {Component, Input, Output, EventEmitter, OnInit, AfterContentInit} from 'angular2/core'; import {FORM_DIRECTIVES, NgFor} from 'angular2/common'; import {MenuService} from './menu.service'; import {OrderByPipe} from &apo ...

Strange behavior noticed with Bootstrap accordion

The current behavior of the product specs section is as expected. Clicking on group 1 shows its content, and when clicking on group 2, it minimizes group 1 and displays group 2. However, the issue arises with the next two categories, Usage and Installatio ...

Increment array by 1 if the item is not already present in the array upon clicking the button

I have data stored in my VueJS component as a list, and it is rendered to the DOM using a v-for loop that iterates through each item in the array. I have a button that removes an item from the array, and now I am working on making the add button add back ...

What is the best way to transform a JavaScript object into a chain of interconnected links?

My goal is to transform an object structure like the one below... var obj1 = { firstName: 'John', lastName: 'Green', car: { make: 'Honda', model: 'Civic', revisions: [ { miles: 10150, code: & ...

The function req.isAuthenticated() always returns false and never evaluates to true

My goal is to create user authentication using the following code: userRouter.post("/login", passport.authenticate("local", { session: false }), (req, res) => { if (req.isAuthenticated()) { const { _id, username } = req.user; const t ...

Send a Date Object through an Event Emitter to be used in a Date Picker

I created a personalized Date Picker Child Component, and when the onDateChange event occurs, I intend to send an event to the parent component. @Output() selectedDateChange = new EventEmitter<Date>(); onDateChange($event) { this.selectedDateCha ...

Guide on transmitting information from two separate pages to a PHP script simultaneously using an AJAX request

Looking to gather user information from a form and pass it onto another page smoothly. Origin Site <form action="destination.php" method="post"> Name: <input type="text" name="name"> Email: <input type="text" name="email"> <input typ ...

What is the best method for converting a string picture URL into an image and showcasing it in an image tag?

I have a URL for an image that looks like this: C:\inetpub\MaujApp\OMSAPI\ManualReceivingImages\WhatsApp Image 2021-03-24 at 12.07.41 PM.jpeg My goal is to convert the original image and display it to the user using jQuery. I woul ...