using Backbone.js we have an application, in which on a certain occasion we need to send an ajax post to a clients webservice.
however, the content to be posted, is dynamic, and is decided by a certain array.
for each item in the array we need to go fetch a piece of data.
after assembling the data that aggregated object needs to be sent.
as of now, i have a synchronous approach, though i feel that this is not the best way.
var arrParams = [{id: 1, processed: false},{id: 7, processed: false},{id: 4, processed: false}];
function callback(data) {
$.post()... // jquery ajax to post the data... }
function fetchData(arr, data, callback) {
var currentId = _(arr).find(function(p){ return p.processed === false; }).id; // getting the ID of the first param that has processed on false...
// ajax call fetching the results for that parameter.
$.ajax({
url: 'http://mysuperwebservice.com',
type: 'GET',
dataType: 'json',
data: {id: currentId},
success: function(serviceData) {
data[currentId] = serviceData; // insert it into the data
_(arr).find(function(p){ return p.id === currentId; }).processed = true; // set this param in the array to 'being processed'.
// if more params not processed, call this function again, else continue to callback
if(_(arr).any(function(p){ return p.processed === false }))
{
fetchData(arr, data, callback);
}
else
{
callback(data);
}
},
error: function(){ /* not important fr now, ... */ }
});
}
fetchData(arrParams, {}, callback);
isn't there a way to launch these calls asynchronous and execute the callback only when all results are in?
You have to use JQuery $.Deferred
object to sync them. Look at this article Deferred Docs
You can use in this way:
$.when(
$.ajax({ url : 'url1' }),
$.ajax({ url : 'url2' }) // or even more calls
).done(done_callback).fail(fail_callback);
I would do something like this:
make a function that besides the parameters that you pass to fetchData also gets the index within arrParams, then in a loop call that function for every element. In the success function set processed in your element to true, and check if "you're the last" by going through the array and see if all the rest is true as well.
A bit of optimization can be if you make a counter:
var todo = arrParams.length;
and in the success you do:
if (--todo == 0) {
callback(...)
}
来源:https://stackoverflow.com/questions/10428751/javascript-is-there-a-better-way-to-execute-a-function-after-x-amount-of-async