如何解决这是@cached用于Ember Octane自动跟踪的有效用法吗?
最近,我在使用自动跟踪编写Glimmer组件时遇到了tracked-toolbox的@cached
用例。这是一个示例代码片段:
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
的情况下,上面的代码将在渲染时执行output
getter 3次,分别对msg
,link
和name
执行一次。
我还考虑过为output
构建自己的缓存,但这需要我手动跟踪所使用的状态并对其进行哈希处理,这可能既昂贵又难以维护。
据我了解,@cached
提供的是对自动跟踪系统中“全局标签”的访问,因此我可以依靠该标签来确定何时需要刷新缓存。
由于我目前正在研究的公司项目中不支持此功能,所以我希望这种用法可以鼓励我们以后添加此类支持。
注意:我发现@cached
是
import { createCache,getValue } from '@glimmer/tracking/primitives/cache';
所以从根本上说,我需要的是@glimmer/tracking/primitives/cache
。
解决方法
根据离线讨论在此处发布后续消息。
这是tracked-toolbox中@cached
实用程序的有效用法。狭窄的用例满足以下要求:
-
output
吸气剂很昂贵。 -
output
的结果在JS的其他getter中多次使用。 (如果this.output
仅在模板中直接使用,则其重新运行的语义将与@cache
完全相同。) - 与
output
getter中使用的 values 的显式缓存相比,使用@cache
将不会评估参数值的变化,这意味着{{1 }}设置为与以前相同的值,this.args.b
吸气剂仍将重新运行。在这种使用情况下,这不是问题,因为我知道父级不会在输入args中设置相同的值。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。