Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
986 views
in Technique[技术] by (71.8m points)

jquery - Wait for multiple getJSON calls to finish

I have a loop that makes calls to an API and compiles the results into an array. How do I wait until all of the calls are finished until resuming execution? I see a bunch of answers for how to wait until one call is done, but I don't understand how to check for all of them. If I make a while loop that waits until 'obj' is the correct length, the page just stalls until the calls are done, which is not what I want. Help please?

function getData(id) {
    var thisI = i;
    var url = "www.whatever.com?id=" + id;
    $.getJSON(url, function(data) {
        obj[thisI]=data;
    });
}

obj = [];
for (i=0; i < ids.length; i++) {
    getData(ids[i]);
}

console.log(obj)  //this works! I see all of the elements
document.getElementById("txt").innerHTML=obj[0]['field'];  //TypeError: obj[0] is undefined
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is easy if you use jQuery's deferreds. There is a method, $.when, that waits for multiple promises to complete then runs a callback. That's what you should use here.

Don't use a global obj variable, you can just use the returns from the AJAX calls.

function getData(id) {
    var thisI = i;
    var url = "www.whatever.com?id=" + id;
    return $.getJSON(url);  // this returns a "promise"
}

So, instead of populating obj, we just return the promise. Then in your loop, you collect all of them.

var AJAX = [];
for (i=0; i < ids.length; i++) {
    AJAX.push(getData(ids[i]));
}

Then we need to hook up the callback when all of them are done:

$.when.apply($, AJAX).done(function(){
    // This callback will be called with multiple arguments,
    // one for each AJAX call
    // Each argument is an array with the following structure: [data, statusText, jqXHR]

    // Let's map the arguments into an object, for ease of use
    var obj = [];
    for(var i = 0, len = arguments.length; i < len; i++){
        obj.push(arguments[i][0]);
    }

    document.getElementById("txt").innerHTML = obj[0]['field'];
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...