Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for loop to finish

Tags:

javascript

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 

}
like image 916
Tam2 Avatar asked Oct 31 '13 19:10

Tam2


People also ask

How do you wait for loop to finish?

To use Javascript promises in a for loop, use async / await . This waits for each promiseAction to complete before continuing to the next iteration in the loop.

Can I use await in for loop?

You need to place the loop in an async function, then you can use await and the loop stops the iteration until the promise we're awaiting resolves. You could also use while or do.. while or for loops too with this same structure.

How do you wait for an async function to finish?

Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.


2 Answers

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()

like image 163
jeremy Avatar answered Jan 04 '23 11:01

jeremy


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..
            }
        });
    } 
}
like image 20
SeinopSys Avatar answered Jan 04 '23 11:01

SeinopSys