How to make a clean Asynchronous loop?

Viewed 456

Following typical REST standards, I broke up my resources into separate endpoints and calls. The main two objects in question here are List and Item (and of course, a list has a list of items, as well as some other data associated with it).

So if a user wants to retrieve his lists, he might make a Get request to api/Lists

Then the user might want to get the items in one of those lists and make a Get to api/ListItems/4 where 4 was found from List.listId retrieved in the previous call.

This is all well and good: the options.complete attribute of $.ajax lets me point to a callback method, so I can streamline these two events.

But things get very messy if I want to get the elements for all the lists in question. For example, let's assume I have a library function called makeGetRequest that takes in the end point and callback function, to make this code cleaner. Simply retrieving 3 elements the naive way results in this:

var success1 = function(elements){
    var success2 = function(elements){
       makeGetRequest("api/ListItems/3", finalSuccess);
    }
    makeGetRequest("api/ListItems/2", success2);
}
makeGetRequest("api/ListItems/1", success1);

Disgusting! This is the kind of thing in programming 101 we're smacked across the wrists for and pointed to loops. But how can you do this with a loop, without having to rely on external storage?

for(var i : values){
    makeGetRequest("api/ListItems/" + i, successFunction);
}

function successFunction(items){
    //I am called i-many times, each time only having ONE list's worth of items!
}

And even with storage, I would have to know when all have finished and retrieved their data, and call some master function that retrieves all the collected data and does something with it.

Is there a practice for handling this? This must have been solved many times before...

2 Answers
Related