如何使forEach循环等待每个Ajax函数完成

时间:2018-11-13 06:41:24

标签: javascript jquery ajax loops

我有一个array个语句,我想遍历每个语句并通过server调用提交给ajax。我必须确保在发送下一个请求之前执行每个ajax请求,因为在server端代码上,我正在为此unique key语句创建一个array 。结果是在我可以提交第一个请求之前,第二个请求进入,最后我创建了两个单独的密钥,因为它将每个密钥都视为第一次请求。我不能完全依赖超时,到目前为止,我的代码继续循环。

function formPostSubmission(form){
    var parts = ['a', 'b', 'c'];
    var i = 0;
    parts.forEach(function(entry) {
        i++;
        datafield ={
            answer:entry,
            displayOrder:i,
            ajaxName:'statementPartialSubmit'
        };
        $.when(submitAjaxData(form, datafield)).then(function succesHandler(data){
            console.log("promise test "+data);
            console.log("Below request ");
        },
        function errorHandler(){
            console.log("Error occurred ");
        })
        console.log("Go for next ");
    });
}

function  submitAjaxData(form, datafield) {
    console.log(" called submitAjaxData  ");
    var loadurl = domainName + "/ajax-call-handler";
    return $.ajax({
        url: loadurl,
        method: "GET",
        data: datafield
    });
}

我希望检查响应数据是否成功,然后在循环中进行。但这就是我的console打印的方式。

called submitAjaxData
Go for next
called submitAjaxData 
Go for next
promise test  
Below request
promise test 
Below request 

4 个答案:

答案 0 :(得分:2)

使用承诺:

Map.Entry<ArrayList<Integer>,miniSquare> pair = it.next();

答案 1 :(得分:0)

您可以通过使用await来使用此解决方案,例如:

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

答案 2 :(得分:0)

我编写了此功能 PromiseAllSeq ,以按顺序执行一个promise数组。

您可以选择将回调作为第二个参数传递,但是鉴于您的问题,我根据您的代码整理了一个有效的 demo

console.clear();
/**
 *  Promises will wait for each other and will return any[].
 *  If a promise is rejected it will stop.
 *  @param arr - (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[]
 */
const PromiseAllSeq = (arr, callback) => {

  let result = [];

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

  const rec = (arr) => {

    return new Promise((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);

      }

    })

  }

  return rec(arr);

}

function succesHandler(data, index) {

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

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

  console.log("Go for next ");

  return data;

}

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

function submitAjaxData(form, datafield) {
  console.log("called submitAjaxData  ", datafield);
  //var loadurl = domainName + "/ajax-call-handler";

  // Mock some requests with delayed responses
  // https://reqres.in/#console
  var loadurl = "https://reqres.in/api/users?delay=" + datafield.fakeDelay;
  return $.ajax({
    url: loadurl,
    method: "GET",
    data: datafield
  });
}

function formPostSubmission(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 below
    let 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);
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

答案 3 :(得分:-1)

async: false 

是您情况下的最佳选择