Вопрос по callback, javascript – Есть ли лучший способ объединить несколько обратных вызовов?

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

Это не очень элегантно, но делает работу. Есть ли лучший способ сделать это? Возможно, обертка?

Ваш Ответ

2   ответа
1

Вы можете использоватьjQuery Отложенный объект для этого.

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
}
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.

Похожие вопросы