Meteor Observer Reuse:将更改我的发布返回查询以不使用this.userId使我的观察者更可重用?

时间:2016-11-17 22:16:30

标签: meteor meteor-publications

我有一个发布,它返回一个如下所示的游标:

// Publication RETURNS THIS QUERY

Notepads.find({_id: notepadId, $or: [{userId: this.userId}, {'collaborators.userId': this.userId}], archived: false})

正如您所看到的,查询对用户来说是唯一的,因为它包含this.userId

我在出版物中使用this.userId作为安全形式。如果您与该特定记事本相关联,则只会返回数据。

在我的应用中,多人可以在一个记事本上进行协作。那么为了使观察者更可重复使用,这种调整是否有助于我的应用?

// Optimized publication

notepad = Notepads.findOne({_id: notepadId, $or: [{userId: @userId}, {'collaborators.userId': @userId}], archived: false})

if notepad?
  // Optimized publication RETURNS THIS QUERY 
  return Notepads.find({_id: notepad._id, archived: false})
else
  return

我认为这是观察者重用的意思。该发布为订阅它的任何用户返回完全相同的查询。这是正确的,这种优化值得改变吗?

2 个答案:

答案 0 :(得分:0)

Quoting from kadira.io on How Observers are Handled in Meteor:

  

为了创建相同的观察者,您需要创建游标   用:

     
      
  • 同一集合
  •   
  • 相同的选择器(查询)
  •   
  • 同一组选项(包括排序,限制等)
  •   

在您的示例中,不同用户的选择器不同。

选择器为Object Literals并在传递到.find调用之前进行评估。这意味着{_id: notepad._id, archived: false}变为

  • {_id: 'myNotebookID', archived: false}
  • {_id: 'anotherNotebookId', archived: false}

正如您所看到的,在您解析notepad._id后,这些是不同的选择器,这在传递给.find()之前就会发生。

如果您的第一个数据库查询返回了相同的记事本,因为您的第二个用户是第一个用户笔记本上的协作者,您最终会得到相同的选择器和一个游标/可观察对象。然而,对于大多数应用程序而言,这可能不足以进行优化,尤其是(如@Khang指出)您将失去反应性。

所以,它不是同一个查询,它不会重复使用观察者,并且不值得改变。

答案 1 :(得分:0)

您的优化版本存在问题,即不响应。因为您使用Notepads.findOne作为安全检查来确保用户可以访问该文档。

内部发布.findOne不是被动的,例如在执行发布时,用户无权访问该文档,因此没有任何内容发送给客户端,然后将用户添加为协作者,但不做任何更改,因为出版物将重新运行。