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

Prevent invalidating subscription iterator #1438

Merged
merged 5 commits into from Dec 25, 2019
Merged

Prevent invalidating subscription iterator #1438

merged 5 commits into from Dec 25, 2019

Conversation

cngu
Copy link
Contributor

@cngu cngu commented Nov 2, 2018

This change shallow copies _subscribers before iterating over it, in-case one of the subscription listeners attempts to unsubscribe synchronously and invalidate the iterator.

src/store.js Outdated
@@ -100,7 +100,7 @@ export class Store {
handler(payload)
})
})
this._subscribers.forEach(sub => sub(mutation, this.state))
this._subscribers.slice().forEach(sub => sub(mutation, this.state))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm open to cleaner/faster ways to generate a shallow copy.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's ok to use slice for that.

@ktsn
Copy link
Member

ktsn commented Nov 5, 2018

What is the actual use case that unsubscribing in another subscribe handler by the way?

@cngu
Copy link
Contributor Author

cngu commented Nov 5, 2018

It can be useful in scenarios where you want to teardown a subscription when a particular mutation occurs (e.g. logout), or mutations that are guaranteed to only be committed N times during the lifetime of the app (e.g. 1 login from OAuth flow, as another login would have to reload the page).

src/store.js Outdated
@@ -100,7 +100,7 @@ export class Store {
handler(payload)
})
})
this._subscribers.forEach(sub => sub(mutation, this.state))
this._subscribers.slice().forEach(sub => sub(mutation, this.state))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's ok to use slice for that.

@@ -100,7 +100,7 @@ export class Store {
handler(payload)
})
})
this._subscribers.forEach(sub => sub(mutation, this.state))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you write some comment to share the context?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@@ -100,7 +100,7 @@ export class Store {
handler(payload)
})
})
this._subscribers.forEach(sub => sub(mutation, this.state))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we also need to do the same thing for _actionSubscribers in dispatch method.
https://github.com/vuejs/vuex/blob/dev/src/store.js#L132

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I've shared it through a new notifySubscribers function.

@cngu
Copy link
Contributor Author

cngu commented Dec 25, 2019

Hi @ktsn, are there any other changes you'd like to see in this PR?

Copy link
Member

@ktsn ktsn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@ktsn ktsn merged commit e012653 into vuejs:dev Dec 25, 2019
@vue-bot
Copy link

vue-bot commented Dec 25, 2019

Hey @cngu, thank you for your time and effort spent on this PR, contributions like yours help make Vue better for everyone. Cheers! 💚

vaga pushed a commit to vaga/vuex that referenced this pull request Apr 20, 2020
* Prevent users from invalidating the subscription iterator by synchronously calling unsubscribe

* Prevent users from invalidating the action subscription iterator by synchronously calling unsubscribe

* Fix commit subscribers argument invocation
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

Successfully merging this pull request may close these issues.

None yet

3 participants