我有一个函数,它有一个$ .each来循环对象的键并执行操作。在这个循环中,我正在调用一个函数,该函数反过来调用服务器来获取一些数据并在回调中处理它。这些调用是异步的,因此$ .each不会等待数据到来,并且回调会执行它应该执行的操作并继续迭代。如何使$ .each循环等到我完成操作然后继续。
$.each(messages,function(key) {
//do something
if(some Condition) {
getfromserver(token,myCallback); }
//do something
});
function myCallback(data)
{
//do something with data
}
答案 0 :(得分:1)
你可以这样做而不是$.each
,我称之为回调循环:
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
}
答案 1 :(得分:0)
你不能用简单的迭代。相反,你应该这样做:
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();
答案 2 :(得分:0)
将循环添加到回调中的基本思路
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();
}
有很多方法可以建立一个电话队列。
答案 3 :(得分:0)
这是在coffeescript中,但我认为它可以满足您的需求。你继续将执行转发到函数中,就像在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/