Skip to content

Reactive declarations are reordered in compiled files and run in unexpected order #5905

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
cbxp opened this issue Jan 19, 2021 · 4 comments
Closed

Comments

@cbxp
Copy link

cbxp commented Jan 19, 2021

Describe the bug

It seems that developer cannot control the order of execution of reactive statements prefixed with $:

Given the source (where it is very important to run init first):

  $: init(object)
  $: if (indentsLocked) {
    if (object.ridgeIndentLeft < object.width / 2) object.ridgeIndentRight = object.ridgeIndentLeft
    else object.ridgeIndentRight = object.width - object.ridgeIndentLeft
  }
  $: if (overhangsLocked) object.overhangSide = object.overhangBottom

The compiler reorders the init to be last:

	$$self.$$.update = () => {
		if ($$self.$$.dirty[0] & /*indentsLocked, object*/ 3) {
			$: if (indentsLocked) {
				if (object.ridgeIndentLeft < object.width / 2) $$invalidate(0, object.ridgeIndentRight = object.ridgeIndentLeft, object); else $$invalidate(0, object.ridgeIndentRight = object.width - object.ridgeIndentLeft, object);
				console.log(object.ridgeIndentRight);
				debugger;
			}
		}

		if ($$self.$$.dirty[0] & /*overhangsLocked, object*/ 5) {
			$: if (overhangsLocked) $$invalidate(0, object.overhangSide = object.overhangBottom, object);
		}

		if ($$self.$$.dirty[0] & /*object*/ 1) {
			$: init(object);
		}
	};

Logs
Not relevant

To Reproduce
https://svelte.dev/repl/f1ae2c3d30034d519c13cd647989d0b0?version=3.31.2

Expected behavior
Developer can control the order of execution, Preferably, the order is the same as defined in source file.

Stacktraces
If you have a stack trace to include, we recommend putting inside a <details> block for the sake of the thread's readability:

Information about your Svelte project:
System:
OS: Linux 5.4 Ubuntu 20.04.1 LTS (Focal Fossa)
CPU: (8) x64 Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz
Memory: 2.97 GB / 15.59 GB
Container: Yes
Shell: 5.0.17 - /bin/bash
Binaries:
Node: 15.0.1 - /usr/local/bin/node
npm: 7.0.3 - /usr/local/bin/npm
Browsers:
Chrome: 87.0.4280.141
Firefox: 84.0.2
npmPackages:
svelte: ^3.31.2 => 3.31.2

We use snowpack (probably not relevant)

Severity
Not easy to find a workaround, because reordering of reactive statements is undocumented.

@shibusalim
Copy link

Very good

@Conduitry
Copy link
Member

They're ordered according to the dependencies that the compiler can see in the reactive blocks. $: init(object) looks like it would depend on other blocks where object is assigned to, so it gets run later. It's not currently documented outside of issue comments, but it's not a bug.

@dummdidumm
Copy link
Member

dummdidumm commented Jan 19, 2021

Following up on Conduitry's general explanation, here's how you do it in your case:

  $: init(object)
  $: if (indentsLocked) {
    changeRidgeIndentRight(object);
  }
  $: if (overhangsLocked) changeOverhangSide(object)

-> no assignment to object at the $-level, instead inside functions, which the Svelte compiler does not track for reordering.

@cbxp
Copy link
Author

cbxp commented Jan 19, 2021

@Conduitry thanks for clarification, but what is the recommended way to enforce the correct order if compiler does it wrongly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants