Skip to content
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

$store and store.subscribe behave differently #5520

Open
BulatDashiev opened this issue Oct 12, 2020 · 4 comments
Open

$store and store.subscribe behave differently #5520

BulatDashiev opened this issue Oct 12, 2020 · 4 comments

Comments

@BulatDashiev
Copy link

Describe the bug
Open console in this repl
in synchronous for loop store.subscribe runs callback for each set, while reactive $: runs only on last set

const store = writable(0);
	
setTimeout(() => {
	for (let i = 1; i <= 10; ++i) {
		store.set(i); // syncronous set calls
	}
});
	
$: console.log('$:', $store); // logs only last value
store.subscribe(v => console.log('subscribe', v)); // logs each value

Expected behavior
Autosubscription and manual subscription should behave the same way or explained in documentation

Severity
Might broke some logic, if you expect all callback of set to run in autosubscription.
I think this should be clarified in documentation.

@Conduitry
Copy link
Member

This is expected. It's not that $store doesn't update right away, it's that $: only runs at most once per microtask.

@davidsavoie1
Copy link

I've made a reproduction of the issue in a REPL, where using either the increment or the fetch buttons should switch a loading store to false for one second.

Using $store directly in markup or subscribing manually to it works fine in either case. Using a reactive statement works only if the update is done via a direct update call, but NOT when reacting to value increment.

If I use await tick() before updating the loading store, reactive assignment works as expected in both cases.

This to me is very confusing and misleading, since I was expecting $store to be syntactic sugar for a manual subscription with lifecycle safety, but it is obviously quite different. I don't really understand how microtask management is affecting this behavior, since the value of the store has plenty of time to get updated.

Thanks for the help...

@davidsavoie1
Copy link

I just looked at the issue reproduction I had made and I now understand what I was doing wrong (I've learned the hard way when dealing with other similar issues): The order of the reactive statements is important.

Doing

$: loading2 = $loading;
$: {
  value;
  loading.fetch();
}

is not the same as

$: {
  value;
  loading.fetch();
}
$: loading2 = $loading;

It seems obvious now that I understand it, but reactive assignments and statements seem so magical sometimes that it's easy to forget basic principles.

@stale
Copy link

stale bot commented Dec 24, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale-bot label Dec 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants