Reputation: 781
I have a function that has a $.each to loop over keys of an object and do stuff. within this loop i am calling a function which in turns makes a call to the server to get some data and does things with it in a callback. these calls are asynchronous so the $.each does not wait for the data to come and the callback to do what its supposed to and keeps iterating. How do i make the $.each loop wait till i complete my operation and then continue.
$.each(messages,function(key) {
//do something
if(some Condition) {
getfromserver(token,myCallback); }
//do something
});
function myCallback(data)
{
//do something with data
}
Upvotes: 1
Views: 4069
Reputation: 9009
This is in coffeescript, but I think it does what you need. You keep throwing execution forward into a function, much like in nodejs:
processMessages = (messages, callback, args) ->
# End it by returning the callback result when messages are done
return callback() unless messages.length
# Shift the first message off the list
message = messages.shift()
# Send it to the server for something to do
$.ajax
url: '/echo/json/'
method: 'POST'
data:
json: JSON.stringify({ message: message, args: args })
dataType: 'json'
success:(data) ->
# Respond to the server's response
console.log 'Got ' + data.message
# Process the remaining messages
processMessages messages, callback, args
finished = ->
console.log 'all done here'
processMessages ['hi', 'bob'], finished, 'yo'
Coffeescript: http://jsfiddle.net/datashaman/22gDa/3/
Javascript fork: http://jsfiddle.net/datashaman/3zdQ8/1/
Upvotes: 0
Reputation: 4382
You can't with a simple iteration. Instead you should do this:
function unqueue() {
if (!messages.length)
return;
var key = messages.pop();
// do something
getfromserver(token, myCallback);
//do something
}
function myCallback(data) {
//do something with data
// Repeat it until messages is not empty
unqueue();
}
unqueue();
Upvotes: 0
Reputation: 12961
You can do this instead of $.each
, I call it callback loop:
iterate(messages, 0);
function iterate(arr, i) {
if(i==arr.length) return;
var message = arr[i];
//you might want to create your token based on current message
var token = "...";
if(/*some Condition*/){
getfromserver(token, function (data) {
myCallback(data);
iterate(arr, i++);
});
}
//use this else if you want to do something like 'continue'
//and don't use it if it kinda 'break'
else iterate(arr, i++);
}
function myCallback(data) {
//do something with data
}
Upvotes: 1
Reputation: 207501
Basic idea of adding the loop into your callback
var messages = {foo:"1","bar":2,"asdf":3};
var keys = $.map(messages, function(val, key) { return key});
function makeCall() {
if(!keys.length) return;
var next = keys.shift();
var token = messages[next];
getfromserver(token,myCallback);
}
function myCallback(data)
{
//do something with data
makeCall();
}
There are tons of ways of building up a queue of calls.
Upvotes: 0