反应语句的执行顺序是什么?

What is the order that reactive statements are executed in?

假设我们有以下组件脚本

let x = 0;

function increase() {
    x += 1;
}

$: console.log(x)

$: if (x == 4) {
    x = 0;
}

https://svelte.dev/repl/2bca979673114afea9fc6b37434653a3?version=3.29.0

直觉上我希望通过连续调用 increase,将值 0,1,2,3,4,1,2,3,4,... 记录到控制台。但这种情况并非如此。相反,第二个反应语句首先运行,并且 4 永远不会被记录;它是 0。切换反应语句的顺序没有效果。

如何使日志记录语句先于另一个语句执行,它先运行后运行的原因是什么?

依赖于相同变量的反应语句的顺序 运行 是 不是 Svelte 指定/保证的。您必须构建您的组件,并期望它们可以 运行 以任何顺序排列,并确保您的代码不依赖于任何特定顺序。

您也不能依赖于您在特定情况下观察到的给定顺序——它可能会随着 Svelte 内部实现的变化(例如新的优化)或您自己组件的代码发生变化(导致不同的编译器输出,可能会因 hard-to-anticipate 原因而改变反应块的顺序)。

发生这种情况的原因是高度技术性的(即我真的不知道),但它们归结为易于实现/优化编译器。响应式语句是一种异步操作,通常不能保证执行顺序。

如果您确实需要 2 个操作以特定顺序发生,那么为了安心,您需要在 相同 反应块中进行它们。

    $: {
        console.log(x)     // op 1
        if (x == 4) x = 0  // op 2
    }