骨干网竞态.获取集合

Race Condition of Backbone.Collection fetch

本文关键字:集合 获取 骨干网      更新时间:2023-09-26

我在选定的月份生成日期列表,其中对于每个日期,我将进行Backbone.Collection取回。

下面是我如何循环一个月中的每一个日期

for (var i = 1; i <= numOfDays; i++) {
   var d = i < 10 ? '0'+i:i;
   var v = new View({
      dt: this.year + this.month + (d),
      param: this.array
   });      
   this.$el.append(v.render().el);
}

正如你在上面看到的,每个视图(backbone.view)将代表一个dateparam object。然后在调用render()

时使用UnderscoreJs _.each方法循环param对象
_.each(this.param, this.reading, this);

,然后它将启动一个新的backbone.collection对象,并执行立即获取

reading: function (value, key) {
   var _this = this;
   this.fetchData(new Data.Collection(), '/api/ + value.ipid').done(function(coll) {
      var input = $('<input>').val(value.ipid).attr('data-inid', coll.first().get('in_id'));
      _this.$el.append(input);
   });
}

我像这样分离函数this.fetchData

fetchData: function (obj, url) {
    var deferred = $.Deferred(),
        collection = obj;           
    collection.url = url;
    var xhr = collection.fetch().done(function(data, textStatus, jqXHR) {
        deferred.resolve(collection, data, textStatus, jqXHR);
    }).fail(deferred.reject);
    var promise = deferred.promise();
    promise.abort = _.bind(xhr.abort, xhr);
    return promise;     
}

不幸的是,对于每个视图param对象内item的顺序将发生移位,因为它取决于backbone.ajax的竞争条件。让我们看看param对象

的项目
[{ipid: 44, measure: "cumec"},{ipid: 45, measure: "meter"},{ipid: 46, measure: "milimeter"}{ipid: 47, measure: "cumec"}]

对象项顺序正确。44 45 46 47。但是为了在初始传递时获取清单,将在fetch操作之后进行更改。

如何告诉backbonejs或下划线在开始循环param对象中的另一个项之前等待每个取操作完成

我只是希望循环( __each )在继续循环

之前等待取操作完成

希望有人能启发实现这一目标的方法。谢谢大家,祝大家今天愉快。

如果在视图创建时创建并附加DOM元素(即在reading函数中),那么从done回调内部引用,元素将以与param数组相同的顺序。

旁注:你可以直接用url实例化collection,不需要在fetch返回的承诺周围包装另一个jQuery承诺。

我认为你的问题的解决方案是使用Async.js库提供的迭代器,所以你的代码看起来像:

async.eachSeries(this.param, _.bind(this.reading, this), yourCallbackWhenTheArrayIsFinished);
reading: function (value, callback) {
   var _this = this;
   this.fetchData(new Data.Collection(), '/api/ + value.ipid').done(function(coll) {
      var input = $('<input>').val(value.ipid).attr('data-inid', coll.first().get('in_id'));
      _this.$el.append(input);
      callback();
   });
}

因此,直到从done处理程序调用callback()之前,eachSeries不会处理下一个元素