3 回答
TA贡献1829条经验 获得超7个赞
我认为在你的情况下,你想在商店中保存的不是一个数组,而是一个对象,它会使这一步更容易。像这样:
export const store = readable({} , set => {
let channels = {};
let socket = new WebSocket("ws://localhost:65432");
socket.onmessage = function ({data}) {
let { channel, value } = JSON.parse(data);
// update `channels`
channels = {...channels, [channel]: value };
// set the new `channels` as store value
set(channels)
}
})
请注意,通过这种方式,您将直接将通道作为对象的键:因此,如果通道已经存在,则将更新而不是添加它。如果它不存在,它将被添加。
因此,在您的订阅者中,您可以拥有类似以下内容的内容:
store.subscribe(channels => {
for (let [channel, value] of Object.entries(channels)) {
console.log(`channel ${channel} received ${value}`);
}
});
最后要注意的是,请考虑此代码每次更新都会创建一个新对象以避免副作用,这是常见的做法。但是,如果您对象中有很多数据并且意识到可能的含义,则可以出于性能/内存原因添加/更新单个键而无需每次都复制对象。
希望它有帮助!
TA贡献1943条经验 获得超7个赞
我认为可读的商店不能解决您的问题,因为您在这里没有更新方法。你为什么不试试可写的商店呢?它为您提供了一个以当前值作为参数的更新函数,因此您可以执行如下操作:
let socket = new WebSocket("ws://localhost:65432");
socket.onmessage = function(event) {
var data = JSON.parse(event.data);
var channel = data.channel;
store.update(n => [...n, { id: data.channel, value: data.value }]);
};
下面是一个 REPL,其中包含其工作原理的示例。它使用间隔来模拟 Webhooks 功能。如果打开控制台,则可以看到更新的存储值。
TA贡献1712条经验 获得超3个赞
您也可以在回调中访问可读存储的实际值。然后,您可以更新现有阵列,而无需全部替换:
<script>
import {readable} from 'svelte/store'
let intervalHandle
const arr = new readable(['Start'], (set) => {
intervalHandle = setInterval(() => {
set([...$arr, 'Another value'])
}, 1000)
})
</script>
<h1>Readable demo</h1>
<button on:click={() => clearInterval(intervalHandle)}>Stop it</button>
{#each $arr as item}
<div>{item}</div>
{/each}
添加回答
举报