我对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.
}});
}});
这样可以保证只有在两次提取成功完成后才能运行所需的代码。然而,这显然是低效的,因为提取是一个接一个地连续运行。
执行此操作的更好模式是,并行运行提取,然后在两次提取成功完成后运行一些代码?
答案 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。但是你再次打电话给服务器,而不是多次打电话。