在循环jquery ajax调用时

时间:2018-04-26 01:17:34

标签: javascript jquery ajax

我想使用while循环控制对控制器的ajax调用次数。

var counter = 0;
$('#filter-form').submit(function (event) {
    event.preventDefault();

    alert("counter init = " + counter)
    while (counter < 10) {
        (function () {
            $.ajax({
                url: '/algorithm',
                method: 'GET',
                data: $('#filter-form').serialize() + "&counter=" + counter,
                success: function (data) {
                    alert("The data is " + data);
                    setCounter(parseInt(data))
                },
                error: function (xhr, status, error) {
                    var err = eval("(" + xhr.responseText + ")");
                    alert(err.Message);
                }
            });
        })();
    }
    alert("counter end = " + counter)
});

function setCounter(data) {
    counter = data
}

控制器:

@RequestMapping(value = "/algorithm")
@ResponseBody
public String test(@RequestParam Map<String, String> allRequestParam) {

    int counter = Integer.parseInt(allRequestParam.get("counter"));
    counter++;

    return Integer.toString(counter);
}

控制器基本上只是增加计数器并返回它并在ajax成功:它将全局计数器设置为该数字。

当我这样做时,页面冻结,我无法点击任何内容。我把ajax调用放在一个函数中用于作用域,但它仍然不起作用。当我使用for循环时,似乎ajax没有调用,因为我没有得到任何成功或错误警报。

3 个答案:

答案 0 :(得分:1)

while同步阻止直到达到其条件。即使响应回来,响应也将是异步的;当前线程(while循环)将永远阻塞。

不要阻止。我没有看到任何理由首先使用循环 - 而只是测试计数器是否大于允许的数量,如果是,返回:

$('#filter-form').submit(function (event) {
  event.preventDefault();
  alert("counter init = " + counter)
  if (counter >= 10) return;

如果您想在表单提交上并行发出多个请求,则可以这样做,但您必须跟踪计数器客户端

var counter = 0;
$('#filter-form').submit(function (event) {
  event.preventDefault();
  alert("counter init = " + counter)
  while (counter < 10) {
    counter++;
    // ... make request

答案 1 :(得分:1)

它不起作用的原因很简单:$.ajax调用是异步的。

举个例子:

$(function() {
  var t = 1;
  console.log("Hey, the ajax will start! t's value: " + t);
  $.ajax({
      url: 'www.google.com.br',
      method: 'GET',
      success: function (data) {
          t++;
          console.log("We've received an answer! t's (incremented) value: " + t);
      },
      error: function (xhr, status, error) {
          t++;
          console.log("We've received an error! t's (incremented) value: " + t);
      }
  });
  console.log("Hey, the ajax just ended.... Not really. t's value: " + t);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

输出结果为:

Hey, the ajax will start! t's value: 1
Hey, the ajax just ended.... Not really. t's value: 1
We've received an error! t's (incremented) value: 2

那是因为$.ajax调用非阻塞,因此在程序完成之前不会阻止程序,允许程序继续执行下一行代码并继续运行背景中的ajax任务。

在SO中这是一个经常出现的问题,所以我不会再在此提供解决方案,而是要求您详细了解这些问题:

答案 2 :(得分:0)

正如其他人所说,问题在于呼叫是异步的。这个简单的例子可以让您了解如何控制流程。应该很简单,将它应用到您的案例中。

我正在模拟您的代码工作所需的内容。对于错误,我传回null但你应该冒出任何可能发生的错误,并停止执行或以其他方式处理它们。

var count = 0; // used to store your count

// This represents the function you are 
// waiting on with your ajax calls
function waitOne(num, callback) {
    setTimeout(() => {
        callback(null, num);
    }, 1000);    
}

// This represents your ajax call 
function callWaitOne(callback) {
    waitOne(count, (err, num) => {
        // Your result is here
        console.log(num); 
        // Callback to let the control function
        // know the ajax has returned
        callback(null);    
    });    
}

// This will control the calls
function printWaitOne() {    
    callWaitOne((err) => {
        if (count < 10) {
            count++;
            // Only calls if its callback 
            // has been called.
            printWaitOne();
        }
    });
}

printWaitOne();