Svelte Store疑问:我是否误解了subscribe方法的作用?
Svelte Store Subscribe 误区解析及你的代码问题修复
先纠正你对Subscribe的理解
别被示例误导了——subscribe可不是只用来在组件卸载时绑定unsubscribe的。每次调用store.subscribe(callback),都会干两件事:
- 立刻执行一遍
callback,把当前store的最新值传进去 - 把这个
callback注册下来,之后只要store的值变了,就会触发它
而且,只要你不主动调用subscribe返回的unsubscribe函数,这个订阅就会一直挂着,不会自己消失。
你的代码为啥会打两次日志
分两种常见情况给你拆解:
情况1:组件里用了$store自动订阅
如果你在组件里用了$store这种自动订阅语法,Svelte会悄悄帮你创建一个订阅。当你调用DoThing里的store.update时,这个自动订阅的回调会触发,打一次日志;紧接着调用Notify,里面的subscribe又会立刻执行一次回调,再打一次,就出现了两次日志。
情况2:多次调用DoThing
每次调用DoThing都会新建一个订阅,而且你没取消它。比如第一次调用后,订阅1挂在那儿;第二次调用DoThing时,store.update会触发订阅1的回调打一次日志,然后Notify新建订阅2,又立刻打一次,结果就是两次。
怎么改?
看你需求是想在store更新后通知一次,给你两种靠谱方案:
方案1:用一次就取消订阅
如果只是想获取当前store值打印一次,订阅完立刻取消,不会留下尾巴:
function Notify() { const unsubscribe = store.subscribe(value => console.log(value)); unsubscribe(); // 执行完回调就取消订阅 }
方案2:只创建一次订阅
如果需要每次store更新都通知,别每次调用都新建订阅,只在初始化时建一次:
import { writable } from 'svelte/store' const store = writable(0); // 只注册一次订阅 const unsubscribe = store.subscribe(value => console.log(value)); // 要是在组件里用,记得在组件销毁时取消订阅 // import { onDestroy } from 'svelte'; // onDestroy(unsubscribe); function DoThing(newValues) { store.update(old => newValues); // 直接返回新值就行,不用赋值 }
另外提一句,store.update的回调函数是要返回新值的,你写的oldValues = newValues虽然能跑,但规范写法是return newValues,逻辑更清晰。
内容的提问来源于stack exchange,提问作者JustBarnt
相关产品推荐
相关产品推荐

