【问题标题】:Ember Computed Property Slow and InconsistentEmber 计算属性缓慢且不一致
【发布时间】:2018-01-31 01:34:02
【问题描述】:

我有一个应用程序可以显示视频并允许用户对视频进行评分。平均评分和视频被评分的次数显示在其下方。为了计算这些,我为每个模型添加了计算属性。平均属性依赖于 sum 和 length 计算属性。

/*global Ember */
import DS from 'ember-data';

export default DS.Model.extend({
  title: DS.attr('string'),
  url: DS.attr('string'),
  ratings: DS.hasMany('userrating'),
  users: DS.hasMany('user'),
  rated: DS.attr('boolean'),

  // maps through ratings objects and pulls out the rating property
  // returns an array of integers that represent all of one videos ratings
  numRatings: Ember.computed.mapBy('ratings', 'rating'),

  // returns the sum of a videos ratings
  sum: Ember.computed.sum('numRatings'),

  // returns the number of ratings a video has
  length: Ember.computed('numRatings', function () {
    return this.get('numRatings').length;
  }),

  // returns true if the video has only been rated once
  // this is used to determine if '1 user' or '2 users' etc.
  // should be displayed
  one: Ember.computed('length', function () {
    if (this.get('length') === 1) {
      return true;
    }
  }),

  // returns the average rating of a video
  avg: Ember.computed('length', 'sum', function () {
    return Math.round(this.get('sum') / this.get('length'));
  })
});

我注意到有时总和会代替平均值显示。这通常只发生一秒钟,然后平均值正确显示,但每隔一段时间平均值不会显示。今天,除了一个视频之外的所有视频都可以正确显示,但该视频的平均评分显示为“33/5”。

为什么会这样? 我不应该构建 Ember 计算属性以相互依赖吗? 这只是浏览器速度慢的问题吗?我正在加载一堆视频和图像。

总的来说,我对 Web 开发很陌生,这是我的第一个 Ember 应用。

谢谢!

【问题讨论】:

  • 一些改进:length: computed.readOnly('numRatings.length'), one: computed.equal('length', 1)

标签: javascript ember.js


【解决方案1】:

如果不查看您的整个架构,很难真正知道哪里可能存在性能问题,但我可以看到以下内容:

  • 您与与您的 video 模型关联的 userratinguser 模型有关系
  • 您的 sumlength 计算属性都基于另一个计算值,该计算值本身正在执行 map 以从 rating 对象中提取 rating
  • 您有另一个计算观看length,这纯粹是在代码中的其他地方确定“用户”一词的复数
  • 最后,您有一个 avg 计算,它也在监视其他两个计算属性

现在,再次,我无法真正提供确切的答案,但这里有一些建议(可能)减轻在此处加载您的模型。

  1. 完全消除计算的one。如果您真的想知道是否选择了一个,您可以在组件/控制器端执行此计算,但您可以执行其他操作,例如 Ember.computed.equal('numRatings', 1)
  2. length 属性可以被删除以支持this.get('numRatings.length')
  3. avg 只关注numRatings,这样它只会在特定数字发生变化时重新计算,因为您已经知道sum 无论如何都会更新,所以不妨减少观察到的属性的数量李>

也就是说,如果它仍然表现不稳定,您可能需要确保在 userrating 条目中找到的数据是正确的。如果它仍然感觉很慢或需要花时间计算,您也可以尝试将 mapBy 更改为普通的 JS for 循环,因为它们比使用 Array 方法要快得多(尽管可读性较差)。

祝你好运!

【讨论】:

    【解决方案2】:

    length: Ember.computed('numRatings', 需要是length: Ember.computed('numRatings.[]', -- 你需要观察数组的长度,而不是数组本身(如果值整体发生变化,它只会引发一个标志) 你也可以使用别名属性——Ember.computed.alias('numRatings.length')

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-17
      • 1970-01-01
      • 2012-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-20
      相关资源
      最近更新 更多