如何在Angular信号中使用计算值历史值?实现类似RxJS scan功能
实现类似RxJS scan的信号累积功能
你想要的效果没法直接用computed实现,因为computed是纯计算函数,不会保留状态——每次它重新计算时,都是基于当前依赖的值生成全新结果,没法拿到上一次的计算结果来做累积。
正确的做法是用一个ref来维护累积的列表,再通过watch监听signalA的变化,每次更新时把新值追加进去:
import { ref, watch } from 'vue' // 示例signalA,实际可以是任何响应式信号 const signalA = ref(1) // 用来保存累积结果的signalB const signalB = ref([]) // 监听signalA的变化,更新累积列表 watch(signalA, (newVal) => { // 直接追加新值(性能更优) signalB.value.push(newVal) // 如果需要保持数组不可变性,可以用展开语法: // signalB.value = [...signalB.value, newVal] }, { immediate: true }) // 加上immediate会把signalA的初始值也加入列表
如果需要复用这个逻辑,可以封装成一个类似RxJS scan的工具函数:
import { ref, watch } from 'vue' function scan(sourceSignal, accumulator, initialValue) { const result = ref(initialValue) watch(sourceSignal, (newVal) => { // 用传入的累积函数处理当前值和新值 result.value = accumulator(result.value, newVal) }, { immediate: true }) return result } // 使用示例 const signalA = ref(1) // 实现"将每个新值追加到列表"的逻辑 const signalB = scan(signalA, (acc, val) => [...acc, val], [])
这样signalB就会随着signalA的每次更新,自动把新值追加到列表末尾,完全符合你想要的类似RxJS scan的效果。
内容的提问来源于stack exchange,提问作者Homo Civicus
相关产品推荐
相关产品推荐

