Cómo sincronizar múltiples Backbone.js trae?


Soy un poco nuevo en Backbone.js, pero ya estoy impresionado por todo lo que puede hacer por mí, y estoy tratando de aprender los patrones y las mejores prácticas ahora.

Tengo dos colecciones:

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;

Al cargar mi aplicación, necesito recuperar ambas colecciones del servidor y ejecutar un código de arranque cuando esté garantizado que ambas recuperaciones se han completado.

Así es como lo hice por ahora:

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

Esto funciona, se garantiza que el código necesario se ejecute solo después de ambos obtiene completa con éxito. Sin embargo, es claramente ineficiente, porque las búsquedas se ejecutan en serie, una tras otra.

¿Cuál sería un mejor patrón para hacer esto, para ejecutar los fetches en paralelo y luego ejecutar algún código una vez que ambos fetches se hayan completado con éxito?

Author: Jaanus, 2012-08-29

3 answers

Si estás usando jQuery, usa when:

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

Antecedentes:

Usted pasa uno o más deferreds a $.when. Sucede que el "jqXHR" que devuelve collections implementa la interfaz promise/Deferred que se puede combinar en una nueva promise usando $.when. Las solicitudes serán esencialmente concurrentes (bueno, tanto como javascript lo permite) y la función pasada a .done se ejecutará solo cuando ambas búsquedas tengan éxito.

 51
Author: JayC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-30 04:27:12

Como @JayC dijo que podría usar $.when desde jQuery, otra opción que prefiero es la función after (de Subrayado), que se ejecuta una vez justo después de que se completen las llamadas esperadas.

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});
 28
Author: Daniel Aranda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-19 17:01:53

Me gusta la respuesta de @JayC si tienes que buscar cada colección individualmente. Se podría argumentar que una sola búsqueda al servidor sería mejor en lugar de varias búsquedas. Si está obteniendo estos datos al cargar la aplicación, haría una sola llamada al servidor y luego pasaría los datos a sus colecciones relevantes. Realmente depende de cuántas colecciones tenga que recuperar al cargar la aplicación, pero honestamente prefiero hacer una llamada al servidor y luego pasar los datos a mi correspondiente colecciones.

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

Esto obviamente dependerá si puedes manipular tu api y lo anterior no sigue a REST. Pero, de nuevo, está haciendo una llamada al servidor en lugar de varias llamadas.

 2
Author: TYRONEMICHAEL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-29 07:15:27