Tam2
Tam2

Reputation: 1357

Wait for loop to finish

Is there a way to make sure a for loop has finished before running the next function?

I have a scenario where the user is presented with a list of users, they can select an X number of these users and once they press 'Done' for each user that has been selected I call a REST API service to get some more information on the selected user to add to the 'users' array.

But what's happening is whatever I place after the for loop seems to run before it has finished and therefore there are users missing from it

Sample code below:

function doCreateStory() {
    var users = [];

    // Add logged in user as creator
    users.push({
        "id" : user_id,
        "creator" : true
    });

    // Add all checked users
    for (var i = 0, len = items.length; i < len; i++) {
        if (items[i].properties.accessoryType == Ti.UI.LIST_ACCESSORY_TYPE_CHECKMARK) {
            api.UserSearch({
                "method" : "facebook",
                "id" : items[i].properties.id
            }, function(success, res, code) {
                if (success == 1) {
                    users.push({
                        "id" : res.message._id,
                        "creator" : false
                    });
                } else {
                    // Its broke..
                }
            });
        } 
    }

    // WANT TO DO SOMETHING HERE with 'users' array once loop has finished 

}

Upvotes: 10

Views: 35192

Answers (2)

SeinopSys
SeinopSys

Reputation: 8937

The problem lies in the fact that asyncrounus AJAX requests take time to complete. One way to handle this is by using a condition is your success handler:

var completedRequests = 0;

// Add all checked users
for (var i = 0, len = items.length; i < len; i++) {
    if (items[i].properties.accessoryType == Ti.UI.LIST_ACCESSORY_TYPE_CHECKMARK) {
        api.UserSearch({
            "method" : "facebook",
            "id" : items[i].properties.id
        }, function(success, res, code) {
            if (success == 1) {
                completedRequests++;
                users.push({
                    "id" : res.message._id,
                    "creator" : false
                });
                if (completedRequests === len){
                    //all ajax requests are finished
                }
            } else {
                // Its broke..
            }
        });
    } 
}

Upvotes: 3

jeremy
jeremy

Reputation: 4314

api.UserSearch is an async function. You should keep track of the responses and when they have all come in, then handle the data returned.

var requests = 0;
for (var i = 0, len = items.length; i < len; i++) {
    if (items[i].properties.accessoryType == Ti.UI.LIST_ACCESSORY_TYPE_CHECKMARK) {
        requests++;
        api.UserSearch({
            "method" : "facebook",
            "id" : items[i].properties.id
        }, function(success, res, code) {
            requests--;
            if (success == 1) {
                users.push({
                    "id" : res.message._id,
                    "creator" : false
                });
            } else {
                // Its broke..
            }
            if (requests == 0) done();
        });
    } 
}
function    done() {
    // WANT TO DO SOMETHING HERE with 'users' array once loop has finished 
}

This will increment a counter requests and when they have all come in, it should call the function done()

Upvotes: 20

Related Questions