简体   繁体   English

当我在 JavaScript 中告诉它时,循环不会结束

[英]While loop won't end when I tell it in JavaScript

       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);
              }
            });

What should happen: JSON Array pulled from PHP ( [html] and [next] ).应该发生什么: JSON 阵列从 PHP ( [html] 和 [next] )中拉出。 If [next] is set to 0 (when there are no more entries) - the while loop stops and that should be it.如果 [next] 设置为 0(当没有更多条目时)- while 循环停止,应该就是这样。

What happends: Everything that should, except - when the while() requirement is met (so when hasData is set to 0) - the loop enters into an infinite loop (and it keeps requesting the last entry, forever...until the script becomes "unresponsive")发生了什么:应该的一切,除了 - 当满足 while() 要求时(所以当 hasData 设置为 0 时) - 循环进入无限循环(并且它一直请求最后一个条目,永远......直到脚本变得“反应迟钝”)

ajax sends a request and executes the callback when there is a response. ajax发送请求并在有响应时执行回调。 So what's happening is:所以发生的事情是:

  • fire a request发出请求
  • fire another request触发另一个请求
  • fire another request触发另一个请求
  • fire another request触发另一个请求
  • ... ...

because it's inside a while loop.因为它在一个while循环内。 You're clogging your script up with requests, and the server gets a bunch of requests which it probably cannot handle.您正在用请求阻塞脚本,并且服务器收到一堆它可能无法处理的请求。

Edit: I'm sorry, I missed async: false .编辑:对不起,我错过了async: false However that always makes the browser irresponsive.然而,这总是使浏览器反应迟钝。 The best thing to do would be using async: true and fire another if the conditional says so, but only after you get the response:最好的办法是使用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

As Spycho pointed out, since you're fetching JSON, a more convenient way might be:正如 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

Actually, what your code does is not far from a Denial of Service attack on your own server:)实际上,您的代码所做的与您自己的服务器上的拒绝服务攻击不远:)

The Ajax requests won't block until they are finished, as the others already pointed out.正如其他人已经指出的那样,Ajax 请求在完成之前不会阻塞。 Calling $.ajax returns immediately, the actual request is executed in the background and calls the success callback upon completion.调用$.ajax立即返回,实际请求在后台执行,完成后调用success回调。 This all means that Javascript loops through the while as fast as it can, because nothing stops it.这一切都意味着 Javascript 尽可能快地循环通过while ,因为没有什么能阻止它。 This also means that while your first request tries to finish, Javascript has probably spawned thousands of new requests which all need to be processed by the server.这也意味着,当您的第一个请求尝试完成时,Javascript 可能已经产生了数千个新请求,这些请求都需要由服务器处理。

Your server will become uncomfortable serving so many requests at the same time and slows down (if you check it's CPU and memory usage, you will notice).您的服务器会变得不舒服,同时处理这么多请求并变慢(如果您检查它的 CPU 和 memory 使用情况,您会注意到)。 Because of the server slowing down Javascript will spawn ever more and more requests... until finally the whole system grinds to a halt because Javascript is running out of resources and your server probably, too.由于服务器速度变慢,Javascript 将产生越来越多的请求……直到最后整个系统停止运行,因为 Javascript 资源不足,您的服务器也可能也耗尽了资源。

A while loop is not recommended in your case.在您的情况下不建议使用while循环。 It's better to send one request at a time and check for the return value inside the success callback.最好一次发送一个请求并检查success回调中的返回值。 If it's not 0 yet, spawn another request, and repeat the procedure.如果还不是 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
        }
    });
}

The onCompleted argument would be a callback function that gets executed once your update procedure is completed. onCompleted参数将是一个回调 function,一旦您的更新过程完成,就会执行该回调。 You could use it as follows:您可以按如下方式使用它:

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

The first A letter in AJAX means "asynchronous". AJAX 中的第一个 A 字母表示“异步”。 The browser doesn't wait for the response after the initial $.ajax() call, but calls this function many many times.浏览器在初始$.ajax()调用后不等待响应,而是多次调用此 function。

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

also I suggest you cast your response data to number like我也建议您将您的响应数据转换为类似的数字

hasData = data.next * 1; hasData = data.next * 1;

as sometimes even if JSON returns a number, its not considered to be a number by javascript and comparison有时即使 JSON 返回一个数字,它也不被 javascript 和比较视为数字

hasData != 0有数据!= 0

comes true even if hasData="0"...即使 hasData="0" 也能实现...

Because you have set async to false the browser will hang until a response is available.因为您已将 async 设置为 false,所以浏览器将挂起,直到响应可用。 It's possible that your script is not stuck in an infinite loop, it just waits for the response.您的脚本可能没有陷入无限循环,它只是等待响应。

Check that your server side script actually works.检查您的服务器端脚本是否确实有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM