单个方法内的角度信号多次更新触发效果(或计算)一次

问题描述 投票:0回答:1

在进入信号世界时,我们的团队遇到了看似奇怪的问题。让我们想象一个对信号有影响的组件,它是那里的公共成员。在组件构造函数中,执行一些逻辑,多次更新信号值。预期是,这将通过执行信号值更新相同次数的触发效果来反映,但实际上并不会以这种方式发生。相反,效果是在整个组件初始化结束后第一次触发的。

让我们看一下我在 StackBlitz 上准备的示例 DEMO

  constructor() {
    effect(() => {
      this.effectLogs.push(JSON.stringify(this.valueSignal()));
      if (this.valueSignal().length == 1 || this.valueSignal().length == 2) {
        alert('Im never triggered');
      }
    });

    this.insertFirstValue();
    //  possibly some other logic here
    this.valueSignal.update((val) => [...val, 'constructor-1']);

    setTimeout(() =>
      this.valueSignal.update((val) => [...val, 'constructor-2'])
    );
  }

  ngOnInit() {
    this.valueSignal.update((val) => [...val, 'init-3']);
  }

  private insertFirstValue() {
    this.valueSignal.update((val) => [...val, 'constructor-0']);
  }

此效果设置日志的结果如下所示:

["constructor-0","constructor-1","init-3"]
["constructor-0","constructor-1","init-3","constructor-2"]

由于第一个效果结果已经推送了 3 个值,因此实际上定义的条件警报永远不会触发。在我们的情况下,这有点复杂,因为我们基于某些信号值条件进行存储馈送,这些信号值条件的行为方式相同。

我们从提取有问题的部分开始,希望它能出现在我们的实现中。 DEMO 证明这是一些一般行为。也许这是关于如何在运行时解决这个问题的一些误解,但我还没有找到解决这个问题的实际文档,类似于 Stack Overflow。在示例中,我玩了一会儿,添加了按钮来添加新条目两次,尝试利用计算,添加了超时,所有这些事情似乎都很无助(除了超时)。

angular typescript angular-signals
1个回答
0
投票

信号在发出更新通知时与 Observable 有点不同。

基本思想是信号无故障,有单独的更新/通知阶段。

这意味着,当读取信号时,您知道它们都已更新。

这样做的结果是,并不是每次信号更新都会触发效果。要记住的关键词是“最终”。

信号最终会发出已更新的通知。

在记录数组大小时,这在您的情况下是可见的:

> 4
> 5

说明这一点的基本重现是

const mySignal() = signal(1); 
effect(() => console.log(mySignal());

mySignal.set(2);
mySignal.set(3);
mySignal.set(4);

如果您对此进行测试,您会发现只有

4
会被记录。

© www.soinside.com 2019 - 2024. All rights reserved.