What is the best way to execute two asynchronous calls sequentially in JavaScript?

When using a common generic function for AJAX calls, the initial request retrieves all data from the server and maintains it within local scope. However, subsequent requests are still hitting the server, even when the data is already available locally. This issue occurs because the first request is asynchronous and the processing of the second request begins before the first one is completed. How can we ensure that the second request waits until the first one finishes?

a.js invokes call.js, which contains the AJAX call: get();

b.js also calls the same function. If the data is already in the global variable during the second call, no additional AJAX call should be made: get();

call.js:

var get = function() {
  var global = [];
    if (Object.keys(global).length)
      return global;
    ajaxCall({
      // ...
    }).done(function(data) {
      global = data;
    }).fail(function(err) {
    });
  }

In this scenario, the issue arises because the second request is initiated while the first one is still being processed, resulting in unnecessary duplicated calls to the server.

Answer №1

If you want to ensure only one request is sent to the server at a time, with subsequent requests waiting until the first one is completed

This question has already been answered and requires additional code. For examples, consider searching for "ajax queue" keywords.

Queue AJAX calls

Sequencing ajax requests

It is recommended to use available libraries for this scenario. However, the initial response also includes sample code without the need for an external library.

To send just one request and store the result in cache

The usual approach is to track the existing call.

var isCallInProgress = false;
var global = [];
var get = function() {
if (Object.keys(global).length)
  return global;

if (isCallInProgress)
  return;        

isCallInProgress = true;
ajaxcall({
  // ...
}).done(function(data) {
  global = data;
  isCallInProgress = false;
}).fail(function(err) {
});
}

Depending on the specific requirements, further modifications may be necessary. A more typical API design would involve immediately returning the data if it's already loaded, or executing a callback upon completion:

var isCallInProgress = false;
var global = [];
var get = function(returnCallback) {
 if (Object.keys(global).length){
   // execute callback immediately
   // consider wrapping this in a promise or setTimeout for desired behavior
   returnCallback(global);
 } 

 if (isCallInProgress)
   return;         

 isCallInProgress = true;
 ajaxcall({
   // ...
 }).done(function(data) {
   global = data;
   isCallInProgress = false;

   // async callback
   returnCallback(global);

 }).fail(function(err) {
     // error handling might also be useful for the caller
 });
}

Answer №2

If you want to avoid using the async: false in an ajax call, consider utilizing a control variable instead for better efficiency.

   var requestCompleted = false;
   var fetchData = function() {
      var globalData = [];
        if (Object.keys(globalData).length && requestCompleted)
          return globalData;
        ajaxRequest({
          // ...
        }).done(function(response) {
          globalData = response;
          requestCompleted = true;
        }).fail(function(error) {
      });
   }

Answer №3

Make sure to execute your second request within the callback function of your first request.

var fetch = function() {
  var storage = [];
    if (Object.keys(storage).length)
      return storage;
    ajaxcall({
      // ...
    }).done(function(data1) {
      storage = data1;

      //execute second request here and retrieve data2

    }).fail(function(error) {
    });
  }

The second request will only be triggered once the first request is successful and its callback function is called.

Answer №4

If you encounter a problem, one elegant solution is to utilize the Promises API.

//call.js
var DataPromise = new Promise(function(resolve, reject) {
    ajaxcall({
          // ...
        }).done(resolve).fail(reject);
   });



//a.js
DataPromise.then(function(data) { console.log("a.js now has access to the data"); });


//b.js
DataPromise.then(function(data) { console.log("b.js now has access to the data"); });

By using the Promises API, you can keep track of the status of DataPromise and ensure that ajaxcall is only executed once.

Answer №5

Using the $.ajax method from jQuery will give you a jqXHR object that can be saved and manipulated with different functions.

It is recommended to save this jqXHR or XMLHttpRequest in a variable that is accessible globally. In your functions, make sure to check if this global variable is null before executing any further actions. Once the ajax call is done, remember to clear the variable:

varName = ajaxCall({
    // ...
})
// ...
.always(function(){
    varName = null;
);

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 is the best way to iterate through a puppeteer selector's response in a loop?

So, by using page.evaluate I can accomplish the following: await page.evaluate(function() { var links = document.querySelectorAll('a'); for (var i = 0; i < links.length; i++) console.log(links[i].href); }); However, I am interested in a ...

Using an image as an onclick trigger for a JavaScript function

I am working on a registration page as part of my university project where users can create an account and store their information in a MySQL database. One feature I'm implementing is the ability for users to select an avatar picture. Below is the co ...

Employing JavaScript to set a variable that changes dynamically

In my code, I have a functionality that allows for changing different dropdowns with similar ending IDs. In other parts of the code, I have assigned variables rl and rl_extra as well as rs and rs_extra. Now, when the var prefix is determined to be either ...

Calculating Time Difference in JavaScript Without Utilizing moment.js Library

I have two timestamps that I need to calculate the difference for. var startTimestamp = 1488021704531; var endTimestamp = 1488022516572; I am looking to find the time difference between these two timestamps in hours and minutes using JavaScript, without ...

404 Error: Enhancing RESTFul Service through Ajax

Upon making a RESTful service call using ajax : var request = $.ajax({type: "GET", type : "GET", url : "/services/equipment/searchEquipments?pId="+id, cache : false }); The java method within the service is defined as : @GET @P ...

One way to generate div elements based on the number in an input field when a button is clicked, but ensuring it only happens once

What I am attempting to achieve is: Retrieve data from a JSON file upon button click. Display the data in separate boxes, each one different for every element of the array. For instance, if the JSON provides 3 rows of data, there should be 3 distinct box ...

Tips for retrieving a value from fs.accessAsync function

I am currently working on verifying the accessibility of a specific file, folder, or directory for reading purposes. I have implemented the code below, which functions properly. However, there are a couple of aspects that I would like to inquire about: 1. ...

Firebase issue: The function ref.once is throwing an Uncaught TypeError and is not recognized

I am attempting to utilize Firebase for both uploading a file and storing it in my database simultaneously. I want to track the number of uploads so that I can rename each file uniquely. While I have successfully uploaded and stored a copy in the database, ...

Using express to efficiently redirect from a search form?

As a newcomer to this, my goal is to initiate an external API call after entering a term in a search form and then migrating to a new page displaying the outcomes. Here's what I have accomplished thus far. const express = require('express') ...

The functionality of jquery ujs seems to be impaired when I try to load partials or content remotely using remote calls or

Currently, I am using a piece of jQuery code to populate an element on the webpage with some content: var content = $("#note_"+note.id).html(); $("another_div").html(content); Although this successfully replaces the HTML of the other div, the issue is ...

How to implement caching using XMLHttpRequest?

As someone who has primarily relied on jQuery's AjAX method, I am relatively new to using XMLHttpRequests. However, due to performance concerns in a web worker environment, I now find myself having to resort to the classic XMLHttpRequest. Currently, ...

What is the method for sending an axios post request using the application/x-www-form-urlencoded content type?

How can I successfully send an axios post request using application/x-www-form-urlencoded? I am trying to include a refresh token in the request, but currently an empty object is being sent. However, I have verified that the token exists when checking "us ...

Retrieve a variety of items and pass them to a view using the mssql module in Node

I'm facing an issue while trying to retrieve data from multiple tables and pass them to my view. Below is the snippet of code I've written that's causing the error. router.get('/', function(req, res, next) { sql.connect(config ...

Extracting data from websites using Python's Selenium module, focusing on dynamic links generated through Javascript

Currently, I am in the process of developing a webcrawler using Selenium and Python. However, I have encountered an issue that needs to be addressed. The crawler functions by identifying all links with ListlinkerHref = self.browser.find_elements_by_xpath( ...

When you open the responsive navigation bar, it automatically closes

After creating a website some time ago, I decided to make it responsive by adding a menu. However, I encountered an issue where the menu bar opens but immediately closes after showing the entire list. Here is the HTML code for the menu: <!-- start men ...

Selecting CSS Properties with jQuery

I am trying to make an image change color to blue and also change the background color to blue when it is clicked inside a div. However, my code doesn't seem to be working as expected. Is there a more efficient way to apply CSS to elements? FIDDLE v ...

Executing multiple HTTP requests simultaneously in groups using an asynchronous for loop for each individual request

I'm currently working on running multiple requests simultaneously in batches to an API using an array of keywords. Read Denis Fatkhudinov's article for more insights. The issue I'm facing involves rerunning the request for each keyword with ...

The request made to `http://localhost:3000/auth/signin` returned a 404 error, indicating that

My goal is to access the signin.js file using the path http://localhost:3000/auth/signin Below is my code from [...nextauth].js file: import NextAuth from "next-auth" import Provider from "next-auth/providers/google" export default N ...

Tips for efficiently serving a static file without triggering a disk read

res.sendFile is the preferred method for serving a static file in express. However, it appears that res.sendFile reads the file from disk with each request, as shown below: router.get('/', (req, res) => { res.sendFile('./guest.js&apo ...

Tips for showcasing retrieved JSON with jQuery's ajax functionality

Below is the jquery code I am working with: $.ajax({ type: "POST", url: "Ajax/getTableRecord", data:{ i : id, t: 'mylist'}, dataType: 'json', success: function(data){ alert(data); ...