get computed内部的Emberjs多次向后端发出请求导致无限循环

c9qzyr3d  于 2022-09-28  发布在  其他
关注(0)|答案(1)|浏览(197)

我有一个表,基本上在我的每一行中都有一个get函数,它使用存储服务发出后端请求。但不知何故,当只有一行时,它可以正常工作,但当有多行时,总是尝试重新计算get函数,从而向后端发送无限请求。我正在使用glimmer component
我现在不能在ember端使用模型关系,后端端有深链。这就是我提出后端请求的原因。

  1. get <function_name>() {
  2. return this.store.query('<desired_model_name>', { <dependent1_id>: <dependent1_id_from_args>, <dependent2_id>: <dependent2_id_from_args> });
  3. }

我使用构造函数修复了这个问题。但是你知道为什么这个get函数一直在重新计算吗?Dependent_ids是常数。
奇怪的是,当结果为[]空数组时,它不会每次都重新计算。即使查询结果是相同的,它仍会尝试每次重新计算,并向后端发出无限请求。

pgccezyw

pgccezyw1#

但是你知道为什么这个get函数一直在重新计算吗?
当发生这种情况时,是因为您正在读取稍后更改的@tracked数据(可能在查询完成时)。
因为getters在每次访问时都会重新运行,所以您需要将@cached置于其上,

  1. // cached is available in ember-source 4.1+
  2. // or as early as 3.13 via polyfill:
  3. // https://github.com/ember-polyfills/ember-cached-decorator-polyfill
  4. import { cached } from '@glimmer/tracking';
  5. // ...
  6. @cached
  7. get <function_name>() {
  8. return this.store.query(/* ... */);
  9. }

这确保了在getter上有一个稳定的对象引用,只有在getter中访问的跟踪数据发生更改时,getter的主体才会重新求值。
奇怪的是,当结果为[]空数组时,它不会每次都重新计算。即使查询结果是相同的,它仍会尝试每次重新计算,并向后端发出无限请求。
考虑到这一观察结果,当query完成时,它可能正在更改它自己在初始渲染期间消耗的跟踪数据——在这种情况下,即使使用@cached,您仍然会有一个无限循环(因为在渲染期间访问的跟踪数据正在更改)。
在一个getter中,要绕过这一点是相当困难的。使用构造函数是获取初始数据的一个不错的解决方案,但这意味着您可以选择不使用查询的响应式更新(如果需要,比如如果查询发生更改或其他情况)。
如果您使用的是ember source 3.25+,并且您想要一些更容易使用的东西,也许ember-data-resourecs适合您的需要
上述代码为:

  1. import { query } from 'ember-data-resources';
  2. // ...
  3. // in the class body
  4. data = query(this, 'model name', () => ({ query stuff }));

此处显示文档
这是基于ember-resources中实现资源模式的一些原语构建的,该模式将在下一版本的Ember中出现。

展开查看全部

相关问题