Как сделать чистый асинхронный цикл?

Следуя типичным стандартам REST, я разбил свои ресурсы на отдельные конечные точки и вызовы. Здесь речь идет о двух основных объектах Listи Item(. и, конечно же, у списка есть список элементов, а также некоторые другие данные, связанные с ним ).

Поэтому, если пользователь хочет получить свои списки, он может сделать запрос Get наapi/Lists

Затем пользователь может захотеть получить элементы в одном из этих списков и выполнить Get to api/ListItems/4, где 4 было найдено из List.listId, полученного в предыдущем вызове.

Это все хорошо :атрибут options.completeв $.ajaxпозволяет мне указать метод обратного вызова, поэтому я могу упростить эти два события.

Но все становится очень запутанным, если я хочу получить элементы для всех рассматриваемых списков. Например, предположим, что у меня есть библиотечная функция с именем makeGetRequest, которая принимает конечную точку и функцию обратного вызова, чтобы сделать этот код чище. Простое извлечение 3 элементов наивным способом приводит к этому:

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

Отвратительный! Это то, за что в программировании 101 нас бьют по запястьям и указывают на циклы. Но как сделать это с помощью цикла, не полагаясь на внешнее хранилище?

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!
}

И даже с хранилищем мне нужно было бы знать, когда все закончили и извлекли свои данные, и вызвать какую-то основную функцию, которая извлекает все собранные данные и что-то с ними делает.

Есть ли практика борьбы с этим? Это, должно быть, решалось много раз прежде...

6
задан Nick 15 August 2012 в 14:31
поделиться