What is the best way to ensure that a specific number of XHR callbacks have successfully completed before proceeding with further actions?

I have four requests that each have their own callback and can fire in any order. However, I need all the callbacks to finish successfully before executing mergeData.

The issue with my current approach is that the initial parameter values do not refresh once waitForSync is called (and I am not confident in this method). Can anyone guide me in the right direction?

var heroes = requestDataFromAPI('heroes');
var weapons = requestDataFromAPI('weapons');
var races = requestDataFromAPI('races');
var jobs = requestDataFromAPI('jobs');

waitForSync(heroes, weapons, races, jobs);

...

function waitForSync(heroes, weapons, races, jobs){
  if (heroes && weapons && races && jobs) {
    mergeData(heroes, weapons, races, jobs);
  }
  else {
    setTimeout(waitForSync, '500', heroes, weapons, races, jobs);
  }
}

Answer №1

What types are they? Are they regular XHR objects or jQuery XHRs? Regardless, both will return true when converted to booleans, making the condition also evaluate to true.

You could modify your code to monitor readystate and increase a counter, but I personally prefer using Q promises for a different approach.

This method also allows for easy error handling,

For instance (assuming that requestDataFromAPI returns a jQuery XHR):

// Convert jQuery XHRs into Q promises

var heroesPromise = Q(requestDataFromAPI('heroes'));
var weaponsPromise = Q(requestDataFromAPI('weapons'));
var racesPromise = Q(requestDataFromAPI('races'));
var jobsPromise = Q(requestDataFromAPI('jobs'));

// Wait for all promises to complete

Q.all([heroesPromise, weaponsPromise, racesPromise, jobsPromise])
  .spread(function (heroes, weapons, races, jobs) {
    // Process results
    console.log(heroes, weapons, races, jobs);    
  })
  .catch(function (err) {
    console.log('An error occurred', err);
  })
  .done();

If you're new to promises, I recommend taking the time to learn about them. They simplify handling asynchronous operations and help avoid unnecessary complexities. You won't regret it.

The provided article discusses native promises, but until they are universally supported by browsers, using libraries like Q is necessary. It's also important to note: avoid using jQuery promises as they have limitations (which is why I use Q() wrappers).

Answer №2

To enhance your requestDataFromAPI(String) method, you can modify it as requestDataFromAPI(String, Function), with the callback function as the second parameter.

After completing the requestDataFromAPI call, execute the callback function.

requestDataFromAPI = function(type, callback) {
    ....
    callback();
}

Redefine your entire script in the following manner:

var heroes = false,
weapons = false,
races = false,
jobs = false,
waitForSync= function(){
  if (heroes && weapons && races && jobs) {
    mergeData(heroes, weapons, races, jobs);
  }
};

requestDataFromAPI('heroes', function(){heroes = true; waitForSync();});
requestDataFromAPI('weapons', function(){weapons = true; waitForSync();});
requestDataFromAPI('races', function(){races = true; waitForSync();});
requestDataFromAPI('jobs', function(){jobs = true; waitForSync();});

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

How to dynamically modify a list box with JavaScript

I have an index.html file with a select tag containing multiple options for a drop-down: <label for="edu">Education</label> <select id="edu" name="edu"> <option value="0">10th</option&g ...

Experiencing difficulties with using the javascript alternative to jQuery.ajax()

Here is a JavaScript Object: const data = { name: "John", age: 30, } const jsonData = JSON.stringify(data); The AJAX Request below successfully passes the data: $(function(){ $.ajax({ url:'two.php', ty ...

AngularJS filter that retrieves only values that have an exact match

In my AngularJS application, I have a checkbox that acts as a filter: Here is the data being used: app.controller('listdata', function($scope, $http) { $scope.users = [{ "name": "pravin", "queue": [{ "number": "456", "st ...

Exploring the connections between Ajax, asp.net mvc3 routing, and navigating relative URLs

My ASP.NET MVC3 application is live at a URL like this: http://servername.com/Applications/ApplicationName/ In my code, I am making jQuery AJAX requests in this manner: $.get(('a/b/c'), function (data) {}, "json"); When running the applicati ...

Developing clickable hyperlinks within a jQuery Datatable

I am currently in the process of transitioning from an asp.net GridView Control to a jQuery DataTable with Ajax. On my project's home page, I have a visually appealing image grid that is justified. Each image in this grid acts as a link, redirecting u ...

The connection to the firebase callback

Upon examining this function, it appears that there may be an issue with a null value causing the error message to display: (node:16232) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'groupPages' of null async setTriggers() { ...

Why won't my setTimeout function work?

I'm having trouble working with the setTimeout function, as it doesn't seem to be functioning properly. First and foremost, Player.prototype.playByUrl = function (url) { this.object.data = url; return this.play(); } The co ...

When working with Next.js, I encountered a scenario where the useEffect() function was being triggered twice. I attempted to solve this issue by providing an empty array as the second argument, but to no

When working with Next-JS, I encountered an issue where the useEffect() function was running twice. While I heard that using an empty array as the second argument can fix this in React, it did not work in my case within Next-JS (which is based on React). ...

Learn how to retrieve JSON data from the Yahoo Finance REST API using Angular 2

Currently, I am in the process of developing an application that needs to fetch data from the Yahoo Finance REST API. To retrieve a table for the symbol "GOOG," I have implemented the following code: export class ActService{ act = []; url = 'http ...

Generating a JSON outcome from a SQL server database

My SQL server has the following table layout: Table ( id int, title varchar(40), start Date(), end Date(), allDay bool, username varchar(40) ); I found some code on this blog to create a JSO ...

Assign the value of one variable to another variable using the same keys

I'm facing a scenario where I have two arrays named array1 and array2. My goal is to transfer the values from array2 into array1 for the properties that exist in array1, while keeping the default values for any properties that are not present. One ap ...

Passing along a request using Node.js

I am facing an issue in my project where I need to redirect requests received by a nodejs endpoint to a .NET 7 web API endpoint. The nodejs endpoint is triggered by an external party and it receives the request as expected. However, there seems to be a pro ...

The property 'get' cannot be accessed because the axios module of vue__WEBPACK_IMPORTED_MODULE_0__ is undefined

Having some trouble with Vue and Axios - encountering the following error message: [Vue warn]: Error in created hook: "TypeError: can't access property "get", vue__WEBPACK_IMPORTED_MODULE_0__.default.axios is undefined" Here's the code snippet: ...

The Window.print() function may experience compatibility issues across different browsers

When attempting to utilize the Window.print() function, I encountered an issue where it works perfectly in Google Chrome but not in Mozilla Firefox. Attached are screenshots displaying the problem at hand. What could be causing this discrepancy? Furthermor ...

Explain the operation of recursive function calls in JavaScript

I’ve been working on converting the algorithm found in this Python code snippet into JavaScript. function divide(arr, depth, m) { if (complements.length <= depth) { complements.push(2 ** (depth + 2) + 1); } var complement = comple ...

Using Javascript to change CSS in a Polymer application

Coming from a background in angular and react, I am now delving into the world of polymer. I have a polymer class called myClass with the following template. <div id="[[x]]"> Here, 'x' is a property defined in a property getter. stat ...

Utilize jQuery to perform polling on a web service

I am looking to periodically check a webservice for new messages every hour using jQuery. The ajax call I have in mind looks like this: function checkForMessages(rowid) { $.ajax({ type: "POST", url: "MyPage.aspx/CheckForMessages", contentType: ...

Utilizing Axios to pass multiple values through a parameter as a comma-separated list

Desired query string format: http://fqdn/page?categoryID=1&categoryID=2 Axios get request function: requestCategories () { return axios.get(globalConfig.CATS_URL, { params: { ...(this.category ? { categoryId: this.category } : {}) } ...

Struggling with a component that won't load in JSX?

Having some difficulty with React not rendering data associated with a component's props: import React from 'react'; import {ItemListing} from './ItemListing.js'; export var SearchResults = React.createClass({ render: functi ...

Text will split into two at a later time

I am using the material-ui library. Curious about adding a text followed by a line divider. Here's how I attempted it: <Grid> <Typography variant="h6" color="primary"> {'text'} </Typograph ...