如何同步多个Backbone.js提取?

时间:2012-08-28 22:44:57

标签: concurrency 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.
    }});
}});

这样可以保证只有在两次提取成功完成后才能运行所需的代码。然而,这显然是低效的,因为提取是一个接一个地连续运行。

执行此操作的更好模式是,并行运行提取,然后在两次提取成功完成后运行一些代码?

3 个答案:

答案 0 :(得分:51)

如果您使用的是jQuery,请使用when

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

背景:

您将一个或多个延迟传递给$.when。碰巧集合返回的“jqXHR”实现了promise / Deferred接口,可以使用$.when将其合并为新的promise。这些请求基本上是并发的(好吧,就像javascript允许的那样),传递给.done的函数只有在两次提取都成功时才会执行。

答案 1 :(得分:28)

正如@JayC所说,你可以使用jQuery中的$.when,我更喜欢的其他选项是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});

答案 2 :(得分:2)

如果您必须单独获取每个集合,我喜欢@ JayC的答案。您可以争辩说,与多次提取相比,对服务器的单次提取会更好。如果您在应用程序加载时获取此数据,我会对服务器执行一次调用,然后将数据传递到相关集合。它真的取决于你在应用程序加载时需要获取多少个集合,但老实说,我更愿意调用一次服务器然后将数据传递给我的相关集合。

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

这显然取决于你是否可以操纵你的api并且上面的内容不遵循REST。但是你再次打电话给服务器,而不是多次打电话。