Backbone将多个集合提取到单个集合

时间:2014-04-17 13:51:34

标签: jquery backbone.js promise jquery-deferred

我有两个要合并到一个集合中的集合,我不想使用jquery $.when(A.fetch(), B.fetch()),因为$.when只要其中一个参数失败就会执行失败的回调我不想要其中一个成功,我仍然想用它来渲染。

以下是我出来的方式。我想知道是否有其他方法可以做到这一点,我们可以在没有种族歧视的情况下同时进行吗?

A.fetch().then(function(json) {
     addToMyCollection(json);
}).always(function() {
      B.fetch().then(function(json){ 
           addToMyCollection(json);
      }).always(function() {
           renderViewWithMyCollection();
      });
});

2 个答案:

答案 0 :(得分:1)

您可能希望利用Backbone.Events:

var inject = function(collection) {
  C.add(collection.models)
}

A.on('sync', inject)
B.on('sync', inject)

C.on('add', function() { /* render c */ })

A.fetch()
B.fetch()

如果您只想合并一次,请使用once代替on

上面的代码和你的实现之间的一个关键区别是渲染会发生两次,所以一旦第一个集合同步,第一个集合的项目就会被渲染,当两个集合同步时,所有项目都会被渲染。

如果你想防止这种情况发生,你可以保留一个计数器,在将项目添加到C之后递增它,并在渲染c之前检查它。

答案 1 :(得分:1)

与顺序代码不同,您可以在调用后等待promise。

var pA = A.fetch();
var pB = B.fetch();
pA.then(function(json){
     addToMyCollection(json); 
}).always(function(){ // in better impls, finally
     pB.then(function(res){
         addToMyCollection(res);
     }).always(function(){
         renderViewWithMyCollection();
     });
});

或者,更紧凑;

var pA = A.fetch(), pB = b.fetch();
pA.then(addToMyCollection).always(function(){
      return pB.then(addToMyCollection);
}).always(renderViewWithMyCollection);

你可以用“

”包装这个“已完成”
function always(promise){
     return promise.then(null,function(){}); // ignore rejection
}

然后做:

$.when(always(A.fetch().then(addToMyCollection)),
       always(B.fetch().then(addToMyCollection))).
 then(renderViewWithMyCollection());

当然,像Bluebird这样的真正的承诺库内置了这种功能。