2012-08-28 8 views
24

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.Cómo sincronizar múltiples recuperaciones de Backbone.js?

que tienen 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, lo que necesito para obtener ambas de estas colecciones desde el servidor y ejecutar algún código de arranque cuando está garantizado que los dos recuperaciones han completado.

Así es como lo hice por ahora:

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

Esto funciona, el código necesario se garantiza la ejecución sólo después de tanto Obtiene completa con éxito. Sin embargo, es claramente ineficiente, porque las extracciones se ejecutan en serie, una tras otra.

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

Respuesta

50

Si estás usando jQuery, utilice when:

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

Antecedentes:

se pasa en una o más deferreds a $.when. Ocurre que el "jqXHR" que devuelve la colección implementa la interfaz Promesa/Deferida que puede combinarse en una nueva promesa usando $.when. Las solicitudes serán esencialmente concurrentes (bueno, tanto como javascript lo permita) y la función que se pasa al .done se ejecutará solo cuando ambas recuperaciones sean exitosas.

+0

Gracias. Todas son excelentes respuestas, esta me parece más estética que la versión de guión bajo. Y sí, reestructurar toda la estrategia de carga también es lo que Backbone recomienda en este caso. Pero, a veces, varias adquisiciones y sincronizaciones paralelas son lo apropiado y esto funciona muy bien. – Jaanus

2

Me gusta la respuesta de @ JayC si tiene que buscar cada colección individualmente. Podría argumentar que una única obtención del servidor sería mejor en comparación con las múltiples recuperaciones. Si está buscando estos datos en la carga de la aplicación, haría una única llamada al servidor y luego pasaría los datos a sus colecciones relevantes. Realmente depende de la cantidad de colecciones que tiene que recuperar en la carga de la aplicación, pero sinceramente prefiero hacer una llamada al servidor y luego pasar los datos a mis colecciones relevantes.

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

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

28

Como @JayC dijo que podría usar $.when de jQuery, otra opción que prefiero es la función after (de Underscore), 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}); 
+1

+1 para subrayado. ¡Qué gran pequeña biblioteca! – swatkins

+2

¡Nunca supe de esa pequeña función útil ...! +1. – TYRONEMICHAEL

+0

¡Agradable, eso es muy útil! – gustavohenke

Cuestiones relacionadas