简体   繁体   中英

javascript while loop not working (infinite loop)

Trying to do a while loop using $.getJSON to return progress of a certain task. The initial $.getJSON works flawlessly; however the loop never completes. I am passing certain variables through a backend php file which is the reason for the variables in the script.

$.getJSON('http://anyorigin.com/get?url=https://".$domain.".instructure.com/api/v1/courses/".$course_id."/course_copy/".$id."?access_token=".$token."&callback=?', function(data){
    var progress = data.contents.progress;
    alert(progress);
    var elem = document.getElementById('".$id."');
    elem.style.width = progress + '%';
});

var progress_check = 0;
//The part below doesn't work! //
do {
    $.getJSON('http://anyorigin.com/get?url=https://".$domain.".instructure.com/api/v1/courses/".$course_id."/course_copy/".$id."?access_token=".$token."&callback=?', function(data){
        var progress_check = data.contents.progress;
        alert(progress_check);
        var elem = document.getElementById('".$id."');
        elem.style.width = progress_check + '%';
    });
} 
while (progress_check < 100);

I want the script to update a specific div with a new css style to display the loading bar properly. Here is the div:

<div id='".$id."-div' class='progress progress-striped active'>
   <div id=".$id." class='bar' style='width: 1%'></div>
</div>

Not certain what i am doing wrong. Thanks in advance.

your var progress_check = data.contents.progress; is local variable it becomes zero each time function completes. change it to progress_check = data.contents.progress; and check.

The $.getJSON call is asynchronous - the result isn't known until the AJAX call completes. Furthermore, because the function returns immediately it'll fire as many AJAX calls in parallel as it possibly can. On top of that, your progress variable is being overwritten inside the callback function, so the variable of the same name in the while condition is never updated.

Try this, instead:

function poll(url) {

    var def = $.Deferred();

    (function loop() {
        $.getJSON(url).done(function(data) {
            var progress = data.contents.progress;
            if (progress < 100) {
                def.notify(progress);
                loop();
            } else {
                def.resolve();
            }
        }).fail(def.reject);
    )();

    return def.promise();
}

which abstracts your polling into a function that returns a "promise".

You can then watch for progress events on that promise, and watch for completion of the loop:

poll(myUrl).progress(function(percent) {
    var elem = document.getElementById(...);
    elem.style.width = percent + '%';
}).done(function() {
    // this is called when the loop is finished
}).fail(function() {
    // this is called if any of the AJAX calls break the loop
});

and now your progress display logic is completely separated from the AJAX code, with the only hard-coded dependency in the poll function being which JSON property to look in to find the current progress value.

use javascript timer to make ajax request, make progress track request in every 30seconds/60 seconds
This will be better than do while loop

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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