如何在Svelte中从Promise获取Store并规避顶层声明限制
问题解决:Svelte中await返回的Store无法使用$语法的问题
问题原因
Svelte的自动订阅语法$store要求store变量必须是组件顶层作用域声明的变量。你的代码中,list1和list2是从<#await>的:then块里解构出来的,不属于顶层作用域,编译器无法识别它们为store,因此报错。
解决方案
方案1:顶层声明变量,初始化后赋值
先在组件顶层定义接收store的变量,调用init后将返回的store赋值给这些变量,再用$语法订阅:
<script> import { readable, onMount } from 'svelte/store'; // 模拟业务中的可读store const readable_store1 = readable(['苹果', '香蕉']); const readable_store2 = readable(['红色', '黄色']); async function init(data) { await data; // 这里处理你的业务逻辑 return { list1: readable_store1, list2: readable_store2 }; } // 顶层声明变量用于接收store let list1; let list2; onMount(async () => { const result = await init(Promise.resolve()); list1 = result.list1; list2 = result.list2; }); </script> {#if list1} <ul> {#each $list1 as item} <li>{item}</li> {/each} </ul> {/if}
方案2:手动订阅store,避开$语法限制
如果不想依赖顶层变量,可手动调用store的subscribe方法监听变化,在回调中更新组件状态:
<script> import { readable, onMount, onDestroy } from 'svelte/store'; const readable_store1 = readable(['苹果', '香蕉']); const readable_store2 = readable(['红色', '黄色']); async function init(data) { await data; return { list1: readable_store1, list2: readable_store2 }; } let items = []; let unsubscribe; onMount(async () => { const result = await init(Promise.resolve()); // 手动订阅store unsubscribe = result.list1.subscribe(value => { items = value; }); }); // 组件销毁时取消订阅,避免内存泄漏 onDestroy(() => { if (unsubscribe) unsubscribe(); }); </script> <ul> {#each items as item} <li>{item}</li> {/each} </ul>
方案3:调整init逻辑,直接返回store的值
如果业务允许,可在init中直接获取store的当前值并返回,无需传递store本身:
<script> import { readable, get } from 'svelte/store'; const readable_store1 = readable(['苹果', '香蕉']); const readable_store2 = readable(['红色', '黄色']); async function init(data) { await data; // 用get()获取store当前值 return { list1: get(readable_store1), list2: get(readable_store2) }; } </script> <#await init(Promise.resolve())> {:then {list1, list2}} <ul> {#each list1 as item} <li>{item}</li> {/each} </ul> {/await}
注:此方案仅适用于不需要监听store后续变化的场景,因为返回的是静态值,不会随store更新而变化。
内容的提问来源于stack exchange,提问作者dorphalsig
相关产品推荐
相关产品推荐

