mirror of https://github.com/sveltejs/svelte
fix: disallow effect creation after `await` (#18299)
We incorrectly restore effect context after an`$derived(await ...)` if it occurs inside an async function, but only for those, no other `await` expressions. This is buggy and wrong. We only want to restore context _inside_ an async derived expression (including template expressions)` so that `await a + b` works correctly. It's possible that this will be a breaking change (albeit not semver-violating, because `experimental`) for some people if they are creating effects after an `await` (other than at the top level of a component). This is regrettable, but it should never have worked in the first place.pull/18311/head
parent
d4be4e2973
commit
0da9f9e2ab
@ -0,0 +1,12 @@
|
|||||||
|
import { tick } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, logs }) {
|
||||||
|
await tick();
|
||||||
|
|
||||||
|
assert.deepEqual(logs, [
|
||||||
|
`effect_orphan\n\`$effect\` can only be used inside an effect (e.g. during component initialisation)\nhttps://svelte.dev/e/effect_orphan`
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
<script>
|
||||||
|
async function foo() {
|
||||||
|
await 0;
|
||||||
|
$effect(() => {
|
||||||
|
console.log('this effect is orphaned');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await foo();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -1,14 +0,0 @@
|
|||||||
import { tick } from 'svelte';
|
|
||||||
import { test } from '../../test';
|
|
||||||
|
|
||||||
export default test({
|
|
||||||
async test({ assert, logs }) {
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
||||||
assert.deepEqual(logs, [1, 1]);
|
|
||||||
const [button] = document.querySelectorAll('button');
|
|
||||||
|
|
||||||
button.click();
|
|
||||||
await tick();
|
|
||||||
assert.deepEqual(logs, [1, 1, 2]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
<script>
|
|
||||||
let increment;
|
|
||||||
|
|
||||||
async function fn() {
|
|
||||||
let count = $state(1);
|
|
||||||
increment = () => { count++; };
|
|
||||||
const value = $derived(await count);
|
|
||||||
$effect.pre(() => console.log(value))
|
|
||||||
return { get value() { return value } };
|
|
||||||
}
|
|
||||||
fn().then(r => console.log(r.value));
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<button onclick={() => increment()}>increment</button>
|
|
||||||
Loading…
Reference in new issue