2

最近我在编写带有自动跟踪功能的 Glimmer 组件时遇到了@cachedfrom tracked-toolbox的用例。这是一个示例代码片段:

import Component from '@glimmer/component';

/**
 * Example usage
 * <PersonInfo
 *  @a={{this.objA}}
 *  @b={{this.stringB}}
 *  @c={{this.intC}}
 * />
 * Where objA can be a large object
 */

export default class PersonInfo extends Component {

  /**
   * I hope @cached here can help avoid re-running output getter in each
   * of the other getters, e.g. this.msg, this.link, this.name
   * But whenever any input args changes it triggers update 
   * (i.e. parent run this.objA = newObj)
   */
  get output() {
    return someExpensiveLogic(this.args.a, this.args.b, this.args.c);
  }

  get msg() {
    return translate(this.output.msg);
  }

  get link() {
    return convert(this.output.link);
  }

  get name() {
    return change(this.output.name);
  }
}
{{!-- In the template --}}
<div>
  {{this.name}}
  {{this.msg}}
  {{this.link}}
</div>

如果不使用@cached,上面的代码在渲染时会执行output3 次 getter,每个执行一次msglinkname

我也考虑过为output.

据我了解,@cached提供的是对自动跟踪系统中“全局标签”的访问,因此我可以依靠该标签来确定缓存何时需要刷新。

由于我目前从事的公司项目不支持此功能,因此我希望这种用法可以鼓励我们以后添加此类支持。

注意:我发现这@cached是方便的包装

import { createCache, getValue } from '@glimmer/tracking/primitives/cache';

所以基本上我需要的是@glimmer/tracking/primitives/cache.

4

1 回答 1

2

根据离线讨论在此处发布跟进。

这是tracked-toolbox@cached实用程序的有效用法。狭义用例满足以下要求:

  1. output吸气剂很昂贵。
  2. 的结果output在 JS 的其他 getter 中多次使用。(如果this.output只在模板中直接使用,它在重新运行时的语义已经与使用 . 时完全相同@cache。)
  3. 与getter 中使用的值的显式缓存相比,using不会评估参数值的变化,这意味着如果设置为与以前相同的值,getter 仍将重新运行。在这个用例中这不是问题,因为我知道父级不会在输入参数中设置相同的值。output@cachethis.args.boutput
于 2020-09-24T17:22:18.627 回答