skip to Main Content

I have 2 functions, doFirst() and doSomethingElse(). Now the first function consists of about 10 AJAX Requests which are executed on a condition which checks if that filter was picked. These AJAX Requests are communicating with a URL and save a set of IDs in the respective arrays. After this is done, the doSomethingElse() has to fire which draws the results table. At this point I am executing them by setting a time out. I would like to know a better way to wait for functions to finish and then execute the next function. Any help is greatly appreciated.
Thanks!

            //How I am currently calling the functions:

            doFirst();
            doSomethingElse();



               function doFirst(){
                 var filterArrayTaxSel1 = $("#taxIA span").get().map(el => el.textContent);
                                for (var i = 0; i < filterArrayTaxSel1.length; i++) {
                                    filterArrayTaxSel1[i] = filterArrayTaxSel1[i].replace(" ", "%20");
                                }
                                // taxgroup2 - Selector
                                queryBuilder = filterArrayTaxSel1;
                                //console.log(queryBuilder);
                                console.log(filterArrayTaxSel1);
                                if (filterArrayTaxSel1.length > 0) {
                                    if (filterArrayTaxSel1.length > 0 && filterArrayTaxSel1[0] != "All") {
                                        console.log("I am inside the IF!");
                                        for (var i = 0; i < filterArrayTaxSel1.length; i++) {
                                            var baseURL = "some URL here";
                                            console.log(baseURL);
                                            responses(baseURL);
                                            function responses(baseURL) {
                                                $.ajax({
                                                    url: baseURL,
                                                    type: "get",
                                                    cache: false,
                                                    headers: {
                                                        'Content-Type': 'application/json'
                                                    },
                                                    success: function (data) {
                                                        console.log(data.features.length);
                                                        for (var i = 0; i < data.features.length; i++) {
                                                            if (taxArrayT1.indexOf(data.features[i].properties.taxon_id) == -1) {
                                                                taxArrayT1.push(data.features[i].properties.taxon_id);
                                                            }
                                                        }
                                                        console.log("In the Invertebrate Animals Section 1");
                                                        console.log(taxArrayT1.length);
                                                    }
                                                })
                                            }
                                        }
                                    }
                                    else if (filterArrayTaxSel1[0] == "All") {
                                        console.log("I am inside the IF!");
                                        var baseURL = "some URL here";
                                        console.log(baseURL);
                                        responses(baseURL);
                                        function responses(baseURL) {
                                            $.ajax({
                                                url: baseURL,
                                                type: "get",
                                                cache: false,
                                                headers: {
                                                    'Content-Type': 'application/json'
                                                },
                                                success: function (data) {
                                                    console.log("I am inside the ELSE IF ALLL!");
                                                    console.log(data.features.length);
                                                    for (var i = 0; i < data.features.length; i++) {
                                                        if (taxArrayT1.indexOf(data.features[i].properties.taxon_id) == -1) {
                                                            taxArrayT1.push(data.features[i].properties.taxon_id);
                                                        }
                                                    }
                                                    console.log("In the Invertebrate Animals Section 2");
                                                    console.log(taxArrayT1.length);
                                                }
                                            })
                                        }
                                    }
                                    //Selection 1 Tax Group AJAX Call   Sensitivity ARRAY WITH 0 to Multiple CASES - ENDS.
                                }
     //some more AJAX Calls depending on whether the filter exists
        //End of function
                }



function doSomethingElse(){
//Code to draw the Table using the arrays from the previous function
}

3

Answers


  1. Promise is simply an object to which you can pass some function that does some work, and when it’s finished it invokes a callback function – which you use for further actions.

    You can find full documentation on: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/prototype

    As for example, you have a function, that returns Promise object:

    function makeAjaxCall(url, methodType){
       var promiseObj = new Promise(function(resolve, reject){
          var xhr = new XMLHttpRequest();
          xhr.open(methodType, url, true);
          xhr.send();
          xhr.onreadystatechange = function(){
          if (xhr.readyState === 4){
             if (xhr.status === 200){
                console.log("xhr done successfully");
                var resp = xhr.responseText;
                var respJson = JSON.parse(resp);
                resolve(respJson);
             } else {
                reject(xhr.status);
                console.log("xhr failed");
             }
          } else {
             console.log("xhr processing going on");
          }
       }
       console.log("request sent succesfully");
     });
     return promiseObj;
    }
    

    You then make multiple ajax calls:

    let promise1 = makeAjaxCall(URL1, "GET");
    let promise2 = makeAjaxCall(URL2, "GET");
    let promise3 = makeAjaxCall(URL2, "GET");
    

    Then you have a “listener”, that waits for all promises (ajax calls) to be finished:

    Promise.all([promise1, promise2, promise3]).then(function(values) {
      console.log(values);
    });
    

    You have many articles and documentation on that subject:

    Login or Signup to reply.
  2. The Promise object represents the eventual completion (or failure) of
    an asynchronous operation, and its resulting value.

    Here is an example of how you can use Promise object to make your async code (such as AJAX requests) a bit easier to handle. Promise.all seems like it would be a good candidate to help resolve your issue. You could do something like this:

    const doFirst = () => {
      console.log('Making AJAX requests, please wait..');
      const asyncActions = [
        //Wrap all your async code in a Promise
        new Promise((resolve, reject) => {
          //Resolve some phony data as part of our AJAX request simulation
          setTimeout(() => resolve({
            name: 'Item 1',
            id: 1
          }), 1000)
        }),
        new Promise((resolve, reject) => {
          setTimeout(() => resolve({
            name: 'Item 2',
            id: 2
          }), 4000)
        }),
        Promise.resolve({
          name: 'Item 3',
          id: 3
        })
      ];
    
      //Since all your async actions are stored in a iterable, we can use
      return Promise.all(asyncActions);
    }
    
    const doSomethingElse = values => {
      console.log('Here is the data returned from our AJAX requests:');
      values.forEach(value => {
        console.log(`Name: ${value.name} || ID: ${value.id}`)
      });
    }
    
    doFirst().then(doSomethingElse);
    Login or Signup to reply.
  3. From your code you are using jQuery so you can utilize some of its built in methods. You want to basically keep track of all your Ajax calls in an array so when you make an Ajax call, push them into an array. You can then use jQuery’s $.when() to execute the next step when they are all complete.

    Basic idea:

    function firstStep() {
      var requests = []
      var list = [1,2,3]
      for (var i = 0; i < list.length; i++) {
        requests.push($.ajax(...));
      }
      return requests
    }
    
    function secondStep() {
      console.log(arguments)
    }
    
    var requests = firstStep() 
    $.when.apply(undefined, requests).then(secondStep)
    

    If you were not using jQuery, it would be promises with promise.all

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search