如何在 Svelte 中使用等待块和更新状态

How to use await blocks and update state in Svelte

扩展 https://svelte.dev/tutorial/await-blocks 中的示例,更新 numbers 和使用 await 块的常规方法是什么,还是应该完全避免 await 块?

<script>
    let numbers = [1, 2, 3]
    async function getRandomNumber() {
        const res = await fetch(`tutorial/random-number`);
        const text = await res.text();

        if (res.ok) {
            return text;
        } else {
            throw new Error(text);
        }
    }
    
    let promise = getRandomNumber();

    function handleClick() {
        promise = getRandomNumber();
    }
</script>

<button on:click={handleClick}>
    generate random number
</button>

{#each numbers as number}
<p>
    {number}
</p>
{/each}
{#await promise}
    <p>...waiting</p>
{:catch error}
    <p style="color: red">{error.message}</p>
{/await}

不确定这是否是常规方式,但按如下方式更新 handleClick 似乎可以解决问题:

async function handleClick() {
    promise = getRandomNumber();
    const newNumber = await promise
    numbers = [...numbers, newNumber]
}

Svelte REPL 查看完整结果。

Svelte 只需要知道赋值,你可以使用扩展运算符创建一个新数组,或者你可以只调用赋值。

// option 1
const newNumber = await promise;
numbers.push(newNumber);
numbers = numbers;

// option 2
const newNumber = await promise;
numbers = [...numbers, newNumber]

我个人认为选项 1 是可行的方法,因为它不会分配任何内存来创建新数组,而是修改现有数组。然后赋值只是让编译器知道你修改了数组。

查看 Svelte 文档:https://svelte.dev/docs#2_Assignments_are_reactive

关于在您的示例中使用 {#await} 块纯粹是为了通知用户正在发生某些事情。你有 numbers 这是一个你想要添加数据的数组和一个获取更多数据的承诺。没有一种超级干净的方法可以让 await 块为您完成修改数字的工作,但也没有理由避免使用该块。

例如,这不会更新数据:

{#await promise}
    <p>...waiting</p>
{:then data}
   <!-- html markup here is the convention -->
   <p> {numbers = [...numbers, data]} </p>
{:catch error}
    <p style="color: red">{error.message}</p>
{/await}

数据更新应该在 JS 中完成,而块应该处理显示逻辑。你可以看到上面的内容有点奇怪