You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Svelte中Tauri监听事件更新数组无响应问题排查

问题原因与解决方案

你的猜测是对的,问题确实出在{#await}包裹{#each}的写法上。

核心问题

{#await}块的then分支只会在getMessages()首次resolve时渲染一次,它绑定的是当时的sortedMessages值,后续sortedMessages的响应式更新无法触发这个分支的重新渲染——因为getMessages()已经完成了异步操作,不会再重新执行,自然也不会把更新后的sortedMessages传递给then分支。

修复方案

拆分加载状态和列表渲染逻辑,用条件渲染替代{#await}包裹列表的写法:

  1. 添加加载状态变量
let messages: Message[] = [];
let isLoading = true;
$: sortedMessages = [...messages].sort((a, b) => a.created - b.created);

async function getMessages() {
    isLoading = true;
    const newMessages = <Message[]> await invoke('get_messages', {userId: currentChatInfo?.user.id});
    messages = <Message[]>[...messages, ...newMessages];
    isLoading = false;
}

listen('new-message', (event) => {
    const message: Message = <Message> event.payload;
    if(message.userId === currentChatInfo?.user.id) {
        messages = [...messages, message];
    }
});
  1. 修改模板部分
{#if isLoading}
    <div>loading...</div>
{:else}
    {#each sortedMessages as message}
        <MessageBox {message}/>
    {/each}
{/if}

为什么这样有效

现在sortedMessages的响应式更新会直接触发{#each}块的重新渲染,不再被{#await}的一次性resolve机制限制。加载状态通过isLoading变量单独控制,既保留了初始加载的提示,又能实时响应消息列表的更新。

内容的提问来源于stack exchange,提问作者dscham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 21:25:53