【问题标题】:Meteor: Tracker.autorun and dep.changed causing infinite loopMeteor:Tracker.autorun 和 dep.changed 导致无限循环
【发布时间】:2014-12-02 00:07:04
【问题描述】:

我正在使用新的 Tracker.Dependency 来跟踪几件事,但它会导致下面代码中的自动运行无限运行。怎么了?一旦我将 getSong 和 getSongId 分开以依赖于 dep 和 dep2,而不是仅仅依赖于 dep,下面的代码就可以了。

SongManager = {
  dep: new Tracker.Dependency,
  dep2: new Tracker.Dependency,
  init: function(songId) {
    var self = this;
    this.setSongId(songId);
    Meteor.subscribe('song', songId);
    Tracker.autorun(function(){
      var songs = self.getSongCursor().fetch();
      if (songs.length > 0) {
        self.song = songs[0];
        self.dep.changed();
      }
    })
  },
  getSongCursor: function(){
    return Songs.find({_id: this.getSongId()});
  },
  getSong: function(){
    this.dep.depend();
    return this.song;
  },
  getSongId: function(){
    this.dep2.depend();
    return this.songId;
  },
  setSongId: function(arg){
    this.songId = arg;
    this.dep2.changed();
  },
};

【问题讨论】:

    标签: meteor meteor-tracker


    【解决方案1】:

    问题在于您正在创建循环依赖项。我建议为此使用 ReactiveVar 而不是使用较低级别的依赖 API。

    meteor add reactive-var
    

    那么你可以这样做:

    SongManager = {
    
      song: new ReactiveVar(),
    
      songId: new ReactiveVar(),
    
      init: function(songId) {
        this.songId.set(songId);
        this.computation = Tracker.autorun(_.bind(this.update, this));
      },
    
      update: function() {
        var songId = this.songId.get();
        Meteor.subscribe('song', songId);
        this.song.set(Songs.findOne(songId));
      },
    
      stop: function() {
        this.computation.stop();
      }
    };
    
    SongManager.init(oldSongId);
    SongManager.songId.set(newSongId);
    
    // After enough time has passed for the subscription to update and tracker to flush:
    var currentSong = SongManager.song.get();
    console.log(currentSong._id === newSongId); // true
    

    我还为您添加了一种停止自动运行计算的方法,这样它就不会在不再需要时在后台继续运行。请注意,由于订阅是在自动运行中运行的,因此当songId 更改时,它将自动停止并重新启动。更新函数实际上会运行两次,但 Meteor 知道不会发送两个相同的订阅请求。

    【讨论】:

    • 谢谢,这正是我应该做的。我才意识到我的错误;应该已经定义了 getSongCursor: function(songId){ return Songs.find({_id: songId}); }
    猜你喜欢
    • 2018-10-15
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    • 2021-05-07
    • 2012-08-24
    • 2020-11-16
    • 1970-01-01
    相关资源
    最近更新 更多