Skip to content Skip to sidebar Skip to footer

How To Make A Foreach Loop Wait For Each Ajax Function To Finish

I have an array of statements and I want to loop through each and submit to the server via an ajax call. I have to make sure each ajax request is executed before the next request i

Solution 1:

use promises :

var promises = [];
 for (var i = 0; i < $total_files; i++) {
 // jQuery returns a prom 
   promises.push($.ajax({
  /* your ajax config*/
  }))
 }

Promise.all(promises)
.then(responseList => {
 console.dir(responseList)
 })

Solution 2:

you could use this solution by using await , for example :

for (let f of files) {
    await $.ajax({/* your ajax config*/ });
 }

Solution 3:

I wrote this function, PromiseAllSeq, to execute an array of promises sequentially.

You can pass a callback as the second parameter if you choose, but given your issue i've put together a working demo based on your code.

console.clear();
/**
 *  Promises will wait for each other and will return any[].
 *  If a promise is rejected it will stop.
 *  @paramarr - (Promise<any> | ()=>Promise<any>)[] - Accepts promise or a function that returns a promise
 *  @param callback(response, index) - If callback 'returns' it will overwrite the current response. Useful for changing the response.
 *  @returns any[]
 */constPromiseAllSeq = (arr, callback) => {

  let result = [];

  if (typeof callback !== 'function') {
    callback = () => {};
  }

  constrec = (arr) => {

    returnnewPromise((resolve, reject) => {

      if (arr.length) {

        (typeof arr[0] === 'function' ? arr[0]() : arr[0]).then(res => {

          let cb = callback(res, result.length);

          result = result.concat(typeof cb !== 'undefined' ? cb : res);

          arr.splice(0, 1);

          resolve(arr.length ? rec(arr) : result);

        }).catch(err => {

          reject(err);

        })

      } else {

        resolve(result);

      }

    })

  }

  returnrec(arr);

}

functionsuccesHandler(data, index) {

  // Here i can alter 'data'
  data['finishedPromiseNr'] = index;

  console.log("promise test ", data, index);

  console.log("Go for next ");

  return data;

}

functionerrorHandler(err) {
  console.log("Error occurred ", err);
}

functionsubmitAjaxData(form, datafield) {
  console.log("called submitAjaxData  ", datafield);
  //var loadurl = domainName + "/ajax-call-handler";// Mock some requests with delayed responses// https://reqres.in/#consolevar loadurl = "https://reqres.in/api/users?delay=" + datafield.fakeDelay;
  return $.ajax({
    url: loadurl,
    method: "GET",
    data: datafield
  });
}

functionformPostSubmission(form) {
  var parts = ['a', 'b', 'c'];
  var i = 0;
  let poll = [];
  parts.forEach(function(entry) {
    i++;

    // 'datafield' was not assigned with var or let// Reassigning it on each loop will allow 'datafield' to pass in the anonymous function belowlet datafield = {
      answer: entry,
      displayOrder: i,
      ajaxName: 'statementPartialSubmit',
      fakeDelay: parts.length - i
    };

    // Wrong: submitAjaxData is called, that means, the requests are sent immediately.// poll.push( $.when(submitAjaxData(form, datafield) );// Correct: Wrap and return $.when into a function otherwise 'submitAjaxData' will trigger the requests
    poll.push(() => $.when(submitAjaxData(form, datafield)));

  });

  PromiseAllSeq(poll, succesHandler).then(responseList => {

    console.log('final response');
    console.log(responseList);

  }).catch(errorHandler)


}

formPostSubmission(null);
<scriptsrc="https://code.jquery.com/jquery-3.3.1.min.js"></script>

Solution 4:

async: false

is the best option in your case

Post a Comment for "How To Make A Foreach Loop Wait For Each Ajax Function To Finish"