我想这个问题更多的是关于JS的sysntax,但是我有一个像这样的存储数组,这个存储数组定义了它的set方法来更新来自websockets连接的值。
export const store = readable( {id: 0, value: 0} , set => {
let socket = new WebSocket("ws://localhost:65432");
socket.onmessage = function (event) {
var data = JSON.parse(event.data);
set({id: 0, value: data});
}
})
商店定义了它的set方法来更新来自websockets连接的值. 我怎么能在商店数组中做同样的事? 就像这样。
arr = [];
for(i=0; i<numberOfItems; i++) {
arr = [...arr,{id: i, value: 0}];
}
export const store = readable( [{arr}] , set => {
let socket = new WebSocket("ws://localhost:65432");
socket.onmessage = function (event) {
var data = JSON.parse(event.data);
var channel = data.channel;
set({id: data.channel, value: data.value});
}
})
在这里,我没有办法 "设置 "数组,而且不用每次更新都要声明整个数组。
我想在你的情况下,你想保存在存储中的不是一个数组,而是一个对象,这将使这一步更容易。类似这样。
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}`);
}
});
最后,考虑到这段代码每次更新都会创建一个新的对象,以避免副作用,这是常见的做法。 然而,如果你的对象中有很多数据,并且你意识到可能的影响,你可以直接添加更新单个键,而不需要每次重复对象,这是出于性能内存的考虑。
希望能帮到你!
我认为可读存储不能解决你的问题,因为你这里没有更新方法。你为什么不试着用一个 "可读存储 "来解决你的问题呢?可写商店 而不是?它给了你一个以当前值为参数的更新函数,所以你可以做这样的事情。
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功能。如果你打开控制台,你可以看到更新的存储值。
你也可以在回调里面访问可读存储的实际值。然后你可以更新现有的数组,而不需要全部替换。
<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}