Подтвердить что ты не робот

Как синхронизировать множественные выборки Backbone.js?

Я немного новичок в Backbone.js, но меня уже впечатлило все, что он может сделать для меня, и сейчас я пытаюсь изучить шаблоны и лучшие практики.

У меня есть две коллекции:

var CollA = Backbone.Collection.extend({
    model: ModelA,
    url: '/urlA'
});

var CollB = Backbone.Collection.extend({
    model: ModelB,
    url: '/urlB'
});

var collA = new CollA;
var collB = new CollB;

При загрузке моего приложения мне нужно извлечь обе эти коллекции с сервера и запустить некоторый код начальной загрузки, если он гарантирует, что оба набора завершены.

Вот как я это делал сейчас:

collA.fetch({success: function() {
    collB.fetch({success: function() {
        // run the needed code here.
    }});
}});

Это работает, необходимый код гарантированно запускается только после успешного завершения обоих наборов. Это явно неэффективно, потому что выборки выполняются последовательно, один за другим.

Каким будет лучший шаблон для этого, чтобы запустить выборки в параллель, а затем запустить некоторый код после успешного завершения выборки?

4b9b3361

Ответ 1

Если вы используете jQuery, используйте when:

$.when(collA.fetch(),collB.fetch()).done(function(){
    //success code here.
});

Фон:

Вы передаете одну или несколько отложенных слов на $.when. Так получилось, что "jqXHR", который возвращает коллекций, реализует интерфейс обещания/отсрочки, который можно объединить в новое обещание с помощью $.when. Запросы будут по существу параллельными (ну, насколько позволяет javascript), и функция, переданная в .done, будет выполняться только тогда, когда обе извлечения успешны.

Ответ 2

Как @JayC сказал, что вы можете использовать $.when из jQuery, другим вариантом, который я предпочитаю, является функция after (из Underscore), которая выполняется один раз сразу после завершения ожидаемых вызовов.

http://underscorejs.org/#after

function runMyApp(){
  // run the needed code here.
  console.log('This will run one time but until both fetch are being completed.');
}

//2 because you have two collections
var renderApp = _.after(2, runMyApp);
collA.fetch({success: renderApp});
collB.fetch({success: renderApp});

Ответ 3

Мне нравится @JayC ответ, если вам нужно брать каждую коллекцию отдельно. Вы можете утверждать, что одна выборка на сервер будет лучше, а не на нескольких выборках. Если вы извлекаете эти данные при загрузке приложения, я бы сделал один вызов на сервер, а затем передал данные в соответствующие коллекции. Это действительно зависит от того, сколько коллекций вам нужно получить при загрузке приложения, но я честно предпочитаю сделать один звонок на сервер, а затем передать данные в мои соответствующие коллекции.

$.ajax({
    url: "path/to/app-load-data"
}).done(function(data) { 
    collA = new CollA(data.collA);
    collB = new CollB(data.collB);
});

Это, очевидно, будет зависеть, если вы можете манипулировать своим api, а выше не следовать REST. Но опять же вы делаете один звонок на сервер, а не на несколько вызовов.