虽然我在JavaScript中告诉它时循环不会结束

时间:2011-08-15 11:04:12

标签: php javascript jquery ajax json

       var hasData = '1';
        while (hasData != 0) {
            $.ajax({
            url: '/ajax.php?updateRow='+hasData,
            dataType: 'json',
            async: false,
            success: function(data) {
                hasData = data.next;
                $('.result').append(data.html);
              }
            });

应该怎么做: 从PHP([html]和[next])中提取JSON数组。如果[next]设置为0(当没有更多条目时) - while循环停止,那应该是它。

发生了什么: 应该做的一切,除了 - 当满足while()要求时(所以当hasData设置为0时) - 循环进入一个无限循环(它不断地请求最后一个条目,永远......直到脚本变得“无响应” “)

5 个答案:

答案 0 :(得分:6)

ajax发送请求并在有响应时执行回调。所以发生的事情是:

  • 触发请求
  • 触发另一个请求
  • 触发另一个请求
  • 触发另一个请求
  • ...

因为它在while循环中。你的脚本被请求堵塞了,服务器得到了一堆它可能无法处理的请求。

编辑:对不起,我错过了async: false。然而,这总是使浏览器反应迟钝。最好的办法是使用async: true并在有条件的情况下触发另一个,但只有在得到答案之后才会激活:

function check() {
        $.ajax({
        url: '/ajax.php?updateRow='+hasData,
        dataType: 'json',
        async: true,
        success: function(data) {
            hasData = data.next;
            $('.result').append(data.html);
            if(hasData != 0) check(); // do it again
          }
        });
}

check(); // fire the first request

正如Spycho指出的那样,既然您正在获取JSON,那么更方便的方式可能是:

(function() {

    var fireRequest = function() { // this function is not available anywhere else,
                                   // to avoid having this process running more than once

        $.getJSON('/ajax.php', {updateRow: hasData}, function(data) {
            hasData = data.next;
            $('.result').append(data.html);
            if(hasData != 0) fireRequest(); // do it again
        });

    };

    fireRequest(); // start the process

})(); // call it

答案 1 :(得分:4)

实际上,您的代码所做的与您自己的服务器上的拒绝服务攻击并不远:)

Ajax请求在完成之前不会阻塞,正如其他人已经指出的那样。调用$.ajax会立即返回,实际请求将在后台执行,并在完成后调用success回调。这意味着Javascript尽可能快地遍历while,因为没有什么能阻止它。这也意味着当您的第一个请求尝试完成时,Javascript可能会产生数千个新请求,这些请求都需要由服务器处理。

您的服务器会在同时处理这么多请求并且速度变慢时会感到不舒服(如果您检查它的CPU和内存使用情况,您会注意到)。由于服务器速度减慢,Javascript会产生越来越多的请求......直到最后整个系统停止运行,因为Javascript资源和服务器也可能耗尽。

在您的情况下,不建议使用while循环。最好一次发送一个请求并检查success回调中的返回值。如果它还不是0,则生成另一个请求,并重复该过程。

function updateRows(onCompleted) {
    $.ajax({
        url: '/ajax.php?updateRow='+hasData,
        dataType: 'json',
        success: function(data) {
            hasData = data.next;
            if (hasData == 0) {
               return onCompleted();
            }    

            $('.result').append(data.html);
            updateRows(onCompleted); // not finished yet, recursion
        }
    });
}

onCompleted参数将是一个回调函数,一旦更新过程完成就会执行。您可以按如下方式使用它:

updateRows(function() {
    // Now all rows are updated
    // Proceed with program flow
});

答案 2 :(得分:1)

AJAX中的第一个字母意思是“异步”。在初始$.ajax()调用后,浏览器不会等待响应,但会多次调用此函数。

var hasData = 1;
function ajaxRequest()  {
    $.ajax({
        //...
        success: function(data) {
            hasData = data.next;
            $('.result').append(data.html);
            if (hasData != 0)
            {
                ajaxRequest();
            }
        }
    });
}

答案 3 :(得分:0)

我还建议您将响应数据转换为

之类的数字

hasData = data.next * 1;

有时即使JSON返回一个数字,它也不被javascript和比较视为数字

hasData!= 0

即使hasData =“0”......

也会成真

答案 4 :(得分:0)

由于您已将async设置为false,因此浏览器将挂起,直到响应可用。你的脚本可能没有陷入无限循环,只是等待响应。

检查您的服务器端脚本是否真的有效。