2014-09-13 1 views
0

Вот мой код, чтобы принести некоторые скелетные коллекции одновременно:

$.when.apply(this, _.map(collection_params_pairs, function(pair) { 
    pair.collection.fetch({ 
      data: pair.params, 
      success: function(collection, response) { 
      console.log('success'); 
      } 
    }); 
})).done(function() { 
    console.log('done'); 
}); 

Когда я запускаю его, done получает вход в консоль, прежде чем success. Что я делаю не так?

+3

Что возвращает ваш '_.map'? Я вижу, что он возвращает массив 'undefined', поэтому ничего не ждать' when'. – zerkms

+0

argh, трудно сосредоточиться на пятницу вечером. Благодаря! – tldr

+0

Никто, кажется, не говорит вам, что вам нужно для изменения. Внутри вашего обратного вызова '.map()' вам НУЖНО возвращать обещание, что '$ .when()' может тогда работать. Как и сейчас, вы не передаете никаких обещаний '$ .when()', поэтому ждать нечего. – jfriend00

ответ

3

_.map() звонок в ваш код возвращает массив undefined, поэтому $.when() не имеет никаких обещаний подождать.

Следовательно, он немедленно разрешается.

4

$.when() нуждается в наборе обещаний, чтобы он мог контролировать эти обещания и запускать обработчик .done(), когда все эти обещания сами закончены. Как ваш код структурирован с результатами возврата от _.map(), отправляемых на $.when(), вам необходимо вернуть обещание с функции обратного вызова .map().

Итак ... если предположить, что pair.collection.fetch() уже возвращает обещание (похоже, что он возвращает объект jqXHR который является обещание), вы можете сделать это:

$.when.apply($, _.map(collection_params_pairs, function(pair) { 
    return pair.collection.fetch({ 
      data: pair.params, 
      success: function(collection, response) { 
      console.log('success'); 
      } 
    }); 
})).done(function() { 
    console.log('done'); 
}); 

Если pair.collection.fetch() не возвращает обещание , то вам необходимо создать для того, чтобы использовать $.when():

$.when.apply($, _.map(collection_params_pairs, function(pair) { 
    var def = $.Deferred(); 
    pair.collection.fetch({ 
      data: pair.params, 
      success: function(collection, response) { 
      def.resolve(response); 
      console.log('success'); 
      } 
    }); 
    return def.promise(); 
})).done(function() { 
    console.log('done'); 
}); 

FYI, вы должны, вероятно, также при обработке ошибок на вашем pair.collection.fetch() вызова, как я предполагаю, что есть путь ошибок определенного типа.

+1

«collection.fetch» ​​Backbone возвращает объект jqXHR, который является обещанием - поэтому второй кусок логики (создание отложенного) на самом деле не нужен. –

+0

Просто небольшое примечание: «нужен массив обещаний» --- ему нужны N аргументов (variadics?) – zerkms

Смежные вопросы