我需要为多个值调用异步函数(带循环)并等待这些结果。现在我正在使用以下代码:
(function(){
var when_done = function(r){ alert("Completed. Sum of lengths is: [" + r + "]"); }; // call when ready
var datain = ['google','facebook','youtube','twitter']; // the data to be parsed
var response = {pending:0, fordone:false, data:0}; // control object, "data" holds summed response lengths
response.cb = function(){
// if there are pending requests, or the loop isn't ready yet do nothing
if(response.pending||!response.fordone) return;
// otherwise alert.
return when_done.call(null,response.data);
}
for(var i=0; i<datain; i++)(function(i){
response.pending++; // increment pending requests count
$.ajax({url:'http://www.'+datain[i]+'.com', complete:function(r){
response.data+= (r.responseText.length);
response.pending--; // decrement pending requests count
response.cb(); // call the callback
}});
}(i));
response.fordone = true; // mark the loop as done
response.cb(); // call the callback
}());
这不是很优雅,但它确实起作用。 有没有更好的方法呢?也许是一个包装?
答案 0 :(得分:7)
Async JS拯救(对于客户端和服务器端JavaScript)!您的代码可能如下所示(包括async.js之后):
var datain = ['google','facebook','youtube','twitter'];
var calls = [];
$.each(datain, function(i, el) {
calls.push( function(callback) {
$.ajax({
url : 'http://www.' + el +'.com',
error : function(e) {
callback(e);
},
success : function(r){
callback(null, r);
}
});
});
});
async.parallel(calls, function(err, result) {
/* This function will be called when all calls finish the job! */
/* err holds possible errors, while result is an array of all results */
});
顺便说一句:async还有其他一些非常有用的功能。
顺便说一下2:注意使用$.each
。
答案 1 :(得分:1)
您可以将jQuery Deferred object用于此目的。
var def = $.when.apply(null, xhrs)
xhrs
是一个包含$ .ajax()请求返回值的数组。然后,您可以注册回调def.done(function() { ... });
并使用arguments
类似数组的对象来访问各种请求的响应。要正确处理它们,请移除complete
回调并添加dataType: 'text'
并对done()
使用以下回调:
function() {
var response = Array.prototype.join.call(arguments, '');
// do something with response
}