Perform two separate sets of asynchronous calls with a pause in between each series

I am in need of creating a sequence of AJAX requests to different URLs, and only after all of them have completed I need to initiate another set of calls. This is the code I have written so far:

(function (delay) {
    var tasksToDo = 10,
    currentTask = 0;
    var process = setInterval(function() {
        // make a call
        // blahblahblah
        // then:
        if(currentTask === tasksToDo) {
            clearInterval(process);
        } else {
            currentTask++;
        }
    }, delay);
})(2000);
// The same pattern repeats for the second series, but it will execute immediately due to being asynchronous.

The reason I have structured my code like this instead of using a simple for loop is because I require a pause between each request. The second set of calls cannot begin until the first set is complete, as the URLs needed for the second set are obtained from the completion of the first set; therefore, I cannot merge all the calls into the same self-calling function. It is crucial for the second series to start executing only after the first series has finished.

Answer №1

If you're working with jQuery, utilizing promises can help achieve this task efficiently:

$.when( // initiating first group
    $.ajax({}),
    $.ajax({})
).then(function(){ // executing second group
    $.ajax({});
    $.ajax({});
});

Answer №2

In order to ensure the second series of code is only executed after the first series is complete, we can implement the following pseudocode:

(function (delay) {
    var tasks = 10, 
    currentTask = 0,
    tasksCompleted = 0; 
    process = setInterval(function() {
        // Set up a task
        [...]
        // Create a callback that increments tasksCompleted upon completion
        [...]
        // Execute the task
        [...]
        // Check if all tasks are done
        if(currentTask === tasks) {
            clearInterval(process);

            (function(delay2) {
                // Periodically check if all tasks are completed
                var checkCompletion = setInterval(function() {
                    if (tasksCompleted === tasks) {
                        clearInterval(checkCompletion);
                        // Start executing the second series of tasks
                        [...]
                    }
                }, delay2);
            })(1000); 
        } else {
            currentTask++;
        }
    }, delay);
})(2000);

Answer №3

The choice to use this structure as opposed to a basic for loop is driven by the need for pauses between each operation. It's essential that the second series does not begin until the first series has been completed and I have obtained the necessary URLs for the second set of operations. This prevents me from simply bundling all calls into a continuous self-invoking function. The execution of the second series must be delayed until the first series has concluded.

Is there an alternative to implementing delays for achieving desired outcomes? Consider integrating Promise.all()

var requests = [function doAsyncStuff1() {}, function doAsyncStuff2() {}];

var res = Promise.all(requests.map(function(request) {
  return request()
}));

res.then(function success(data) {
  // handle data from `doAsyncStuff1` , `doAsyncStuff2`
}, function error(err) {
  // process and log any encountered errors
  console.log(err)
});

Answer №4

$http methods return a promise. Utilize the then callbacks to initiate the next ajax request. This involves utilizing the $q service, Angular's promise service, so ensure it is injected into your controller/factory/directive.

var app = angular.module("app",[]);

app.controller("MainCtrl",["$scope","$q","$http",function($scope,$q,$http){
  $scope.log = [];

  //Commence requests for the subsequent set of urls
  function nextSet(urls){
     var deferreds = urls.map(function(url){
         $scope.log.push("Starting url: "+url);
         return $http.get(url);
     });

     //$q.all takes an array of deferreds and will be fulfilled when 
     //all of them resolve.
     return $q.all(deferreds);
  }

  var urlSets = [ 
     [ "https://cors-test.appspot.com/test?1",
       "https://cors-test.appspot.com/test?2" ], 
     [ "https://cors-test.appspot.com/test?3",
       "https://cors-test.appspot.com/test?4",
       "https://cors-test.appspot.com/test?5"] ];
  var dataSets = [];
    
  //The main deferred
  var deferred = $q.defer();

  //Iterate through the sets, chaining 'then'
  //This will effectively create a queue
  //Each chained 'then' callback executes after
  //each set of requests have resolved
  var promise = urlSets.reduce(function(promise,urlSet){

     //return promise for use in the next iteration
     return promise
       
       //Chain the nextSet call, binding the urlSet to the call
       .then(nextSet.bind(null,urlSet))
       
       //An additional chain to indicate completion of previous call
       //Could be used for special processing after fetching each set
       .then(function(dataSet){
         $scope.log.push("Set Finished: "+urlSet.join(","));
         dataSets.push(dataSet);
         return dataSets;
       });

  },deferred.promise);

  //Final 'then' callback triggered upon resolution of all sets
  promise.then(function(dataSets){
    //All operations complete
    $scope.log.push("All done");
    
    //dataSets contains all fetched data from urls
    //it's an array with indexes correlating with urlSets indexes
    console.log(dataSets);
  });
  
  //Start the process
  deferred.resolve();      
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MainCtrl">
  <ul>
    <li ng-repeat="line in log">
      {{line}}
    </li>
   </ul>
</div>

This code expects all URLs to resolve successfully. If any requests fail, subsequent operations will halt. To continue processing even if some requests fail, adjust the code accordingly.

Learn more about Angular's $q service

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 do I dynamically adjust class names for menu items as I scroll using jQuery?

I have a website with different sections identified by unique IDs, such as: <section id="home"> First Section </section> <section id="about_us"> Second Section </section> <section id="what_we_do&q ...

View the gathered HTML content in a fresh browser tab

I'm looking to enhance the reporting system on my website by sending an AJAX request with a progress bar. The server will collect the necessary data, convert it into HTML, and then send it back to me. Upon successful completion of the AJAX request, I ...

Leveraging server-sent events to retrieve an array from a MySQL database using PHP

I've been attempting to implement server-sent events in order to fetch data from a database and dynamically update my HTML page whenever a new message is received. Here's the code I'm using: function update() { if(typeof(Event ...

Looking for answers about JavaScript and SharePoint?

I have a question regarding the interaction between JavaScript and SharePoint. In an ASP page, I created a JavaScript function to retrieve list items from SharePoint. Here is part of my code: $(document).ready(function () { ExecuteOrDelayUntilScriptLoade ...

The validation functionality in AngularJS for a form within an ng-repeat loop is not functioning as intended

In my table, I used the <tr> tag repeatedly with ng-repeat="cancellationPercentData in cancellationPercent" Each tr tag contains a form with name and id set using $index See the code snippet below: <tbody> <tr ng-repeat="cancellatio ...

Developing an npm module that is compatible with both web browsers and Node.js

Currently, I am in the process of developing an npm package that will cater to both web apps and other node modules. If my focus was solely on browsers, I would simply assign window.myExport = myExport; as a direct solution (unless there is a more contemp ...

Preventing the Spread of JavaScript Promises

Consider a scenario where there is a promise chain structured as shown below. The goal is to prevent func3 or func4 from being called when func2 is invoked. AsyncFunction() .then(func1, func2) .then(func3, func4) Currently, throwing an error in func2 res ...

Tips for retaining input field content within a BootstrapVue table

Below is a BootstrapVue table I'm working with; https://i.sstatic.net/xu5Et.png The code, courtesy of this response, is showcased below; new Vue({ el: '#app', data() { return { filter: '', items: [ { i ...

What is the best way to include a context in a JavaScript promise?

Figuring out JS Promises has always been a challenge for me. I'm aware this might be a basic question, but please bear with me. =) Looking at the code snippet below, my goal is to modify a property within the class containing this function (essentiall ...

javascript The unchecking of a checkbox is not functioning

I am facing an issue with this JavaScript code. The problem is that when I uncheck a value, it removes all the values from the result instead of removing just the specific unchecked value. Can someone please help me with this? <script> window.addE ...

Utilizing the js-yaml library to parse a YAML document

Currently, I'm utilizing js-yaml to analyze and extract the data from a yaml file in node js. The yaml file consists of key-value pairs, with some keys having values formatted like this: key : {{ val1 }} {{ val2 }} However, the parsing process enco ...

When I integrate the Google map on my website, it appears to be fully zoomed out by default. However, if you access the map directly through the link provided, it

After creating a custom public map on google.maps, I noticed that the embedded version on my site is zoomed out too far and not centered on my location like the original. You can view it here. Here's the code I'm using to embed the map: <ifr ...

Application unable to save data to file with no indication in error logs

Recently, I've been experimenting with the Capture-Website package, which is designed to save website screenshots to a file. Initially, everything was working smoothly until I decided to restart the server. Now, although my code is running without a ...

The directive 'templateUrl' points to the route '/'

I'm having an issue with using the templateUrl in a directive to load a partial. Whenever I try to visit the URL for the template, it redirects me back to /. This results in the partial loading the entire page instead of just the requested partial. a ...

animations are not triggering when using ng-click inside ng-repeat, is there a reason why the event is not firing?

Check out the code in jsFiddler here After reviewing the code, it's clear that when the add button is clicked, a new item is pushed to the $scope.p. Each item in the ng-repeat loop has an event-binding and everything functions correctly. However, onc ...

Checking the alignment of a label or element in the center of a webpage using javascript

I am new to JavaScript and was attempting to determine if an element is centered aligned by accessing its CSS properties/values. Can someone help me retrieve the CSS property to verify text alignment using JavaScript? ...

default selection in AngularJS select box determined by database ID

Here is the scenario: ... <select ng-model="customer" ng-options="c.name for c in customers"> <option value="">-- choose customer --</option> </select> .... In my controller: $scope.customers = [ {"id":4,"name":"aaaa", ...

get JSON information according to user input/prompt

My goal is to allow the user to select an option and then use that choice to extract specific information from JSON data. I plan to achieve this by implementing a dropdown selection in HTML along with an event listener in JavaScript to fetch the data. va ...

Converting the basic logic from if-else statements to foreach loops was unsuccessful

I am currently working with this function: const applyColor = (value) => { let color //shallow to dark const colors = ['#B3E5FC', '#81D4FA' ,'#4FC3F7', '#29B6F6', '#03A9F4', &ap ...

How to choose the desired day within a specific month when creating a calendar from scratch?

Hi there! I need some assistance. I'm currently working on enhancing a calendar by adding an extra feature. The idea is that when the user selects one or more days, those specific day(s) should be highlighted. However, I'm facing an issue where s ...