2012-05-28 28 views
4

我需要爲多個值調用異步函數(帶循環)並等待這些結果。現在我正在使用下面的代碼:任何更好的方法來結合多個回調?

(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 
}()); 

這並不都是非常優雅,但它的工作。 有沒有更好的方法來做到這一點?也許是一個包裝?

回答

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 */ 
}); 

順便說一句:異步有其他一些真正有用的功能。

順便說一下2:請注意使用$.each

1

您可以使用jQuery Deferred object來實現此目的。

var def = $.when.apply(null, xhrs)xhrs是一個包含$ .ajax()請求的返回值的數組。然後,您可以註冊一個回調def.done(function() { ... });並使用類似數組的對象來訪問各種請求的響應。妥善處理它們,刪除您complete回調,並添加dataType: 'text'和使用done()以下回調:

function() { 
    var response = Array.prototype.join.call(arguments, ''); 
    // do something with response 
} 
相關問題