Can anyone explain more on VueJS Async Update Queue? - vue.js

I am reading the vue official doc on Async Update Queue, and got confused on:
Whenever a data change is observed, it will open a queue and buffer
all the data changes that happen in the same event loop
what does it mean by the same event loop, are there gonna be multiple event loops at the same time? It also says the queue will be flushed in the next event loop “tick”, what does tick mean here? what if there is no next event loop or the next event loop never tick?

Let me try answering this question as par my understanding.
what does it mean by the same event loop, are there gonna be multiple event loops at the same time?
Instead of applying each and every change in any vue property/method/variable to the view, vue saves all those changes in queue and flush those changes later. In this process of pushing the changes in the queue, it optimises by not re-rendering on each change as is commented here:
/**
* Push a watcher into the watcher queue.
* Jobs with duplicate IDs will be skipped unless it's
* pushed when the queue is being flushed.
*/
export function queueWatcher (watcher: Watcher) {
...
...
the queue will be flushed in the next event loop “tick”, what does tick mean here?
Internally Vue tries native Promise.then and MutationObserver for the asynchronous queuing and falls back to setTimeout(fn, 0). Here you can see first preference for this is given to native Promise.then after that MutationObserver where native Promise is not available and in worst case fallback to setTimeout.

Related

How do I hook into the blur event of the v-currency-field?

I'm writing a vue.js application with the v-currency-field package: https://www.npmjs.com/package/v-currency-field
When I read the documentation, I see nothing for a blur event (or any events at all): https://phiny1.github.io/v-currency-field/started.html#introduction
I'm getting around this by selecting the input inside the v-currency-field like this:
const holdbackAmountInput = document.querySelectorAll('[aria-label="Holdback amount"]')[0];
holdbackAmountInput.addEventListener('blur', this.holdbackAmountInputBlurHandler);
But is there not a better way to do this? It gets more complicated than the above code because I have to run it in the updated() hook and check if the holdbackAmountInput exists, and if it does, I have to assign it to a data object so that I have a reference to it when I have to remove the event listener when it's removed from the DOM or when the component is destroyed. Seems needlessly complicated for something that should be really simple.
Is there not a simpler way to do this?

Vuex two commits in same action does not trigger watch

When I watch $store.stateA, the watch callback function for the following seems to not trigger.
stateA: false
muationA(state,val){
state.stateA = val
}
actionA({commit},val) {
commit('mutationA', true)
commit('mutationB', false) //take this out would trigger the watch callback
}
So what is the case here? the entire action callback need to finish before the watch functions are triggered?
As Nit mentioned, both mutations cancel each other since they are done synchronously. Read the "Reactivity in Depth" section of the doc for more info. In particular (emphasis mine):
In case you haven’t noticed yet, Vue performs DOM updates asynchronously. Whenever a data change is observed, it will open a queue and buffer all the data changes that happen in the same event loop. If the same watcher is triggered multiple times, it will be pushed into the queue only once. This buffered de-duplication is important in avoiding unnecessary calculations and DOM manipulations. Then, in the next event loop “tick”, Vue flushes the queue and performs the actual (already de-duped) work.
Other watcher solutions do work differently and are triggered right away when the value changes (e.g. Backbone.js). Vue does not work that way.
I wanted once to use a vuex variable as an event transmitter across components and needed to set a boolean variable to false and immediately to true afterward. I however saw that the watch in the component did not pick it up. The issue as mentioned in the other post is that they cancel each other because they are in the same event loop.
In order to make that work, I just had to separate their event loop by waiting for the Vue.nextTick() as follows:
// First operation
await Vue.nextTick();
// Second operation

Discard handling a network request when a component unmounts

Disclaimer: I know this answer has already been asked, but in my case I need a solution for a specific case that is not really covered by other questions/answers.
In my react-native application, I do a lot of network requests that may take a long time to complete. Each request is handled in two main ways:
The request completed successfully. The global redux/flux state is updated and therefore the nested components are updated as well.
The request throws an error. A network error, a server error, a 400 error, whatever. In this case a message must be displayed to the user, in the form of a message that appears on the screen or as an alert.
My problem is that when a component is unmounted, the fetch callbacks are processed anyway when the request completes. In the first case, this is not a problem: the store is updated successfully and everyone is happy.
In the second case though, it is a problem because:
The alert would be displayed in a different screen, which is not correct and led to problems with the Modal component which I use to present error alerts.
The appearance/disappearance of the error message is controlled by the component LOCAL state, which can not be updated on an unmounted component and therefore throws an error.
What are my possibile solutions here? The most trivial one would be to use in each component a _isMounted property and in each fetch error handler, don't do anything if _isMounted == false. However, this approach is verbose and an antipattern.
Do I have any other option?
If you are using react-navigation I believe you could deduct the state in actions and not call the alert.
My suggestion is that you pass the navigation prop to action method and deduct the navigation state there and call the alert as you require.

Createjs: Stage.update() internal working question for performance optimization. Does it happen at each tick, or each time it's called?

In order to optimize createjs code, I cannot find info on this matter.
Case:
I have a scrollbar component, and each time I move the scrollbar stage is updated to reflect changes in scrollbar visual. Also a scroll event is triggered.
Application listens to the event, and updates some visual in scrolled content, therefore another Stage.update() is triggered.
My question is: does stage get updated only at each "tick", or the above situation will cause stage to update twice in the same instant degrading performance?
In code, will:
stage.update();
stage.update();
stage.update();
Cause stage to update 3 times in a row? Or only once at next tick?
Thank you
There is no debouncing on the stage update, so each time you call it, the stage will be rendered. Additionally, internal counters like tick-based frame advances will be fired.
It is not advisable to run it more times than you need to. Usually apps either have a continuous Ticker, or are updated only when content changes.
If you want to create a hybrid, I recommend checking an update property that you set yourself. Then you can toggle it any time, and it will run once per tick max.
createjs.Ticker.on("tick", function(e) {
if (shouldUpdate) { stage.update(e); }
shouldUpdate = false;
});
Hope that helps!

Angular Subscription in component ngOnInit

I am learning the Angular 5+ and recently comes to the subject/subscription part, I see many tutorial would like to use the subscription in the certain way:
Declare the subscription in component
Subscribe it in ngOnInit via a service's subject or ngrx/store
Unsubscribe it in ngOnDestroy
However, I am not sure if we have to subscribe/unsubscribe every subscription in the component in ngOnInit and ngOnDestroy. For example, if my subscription will get updated through a button click event, which plan should I subscribe it in my component?
Only ngOnInit
Only button click event
Both ngOnInit and button click event
Why would we always subscribe a subscription in ngOnInit? The ngOnInit would be like a Page_Load in page life cycle, so it would only be called once at the very first time, if so whenever the subscription gets updated, will the ngOnInit be fired over and over again? If so, will my component be loaded over and over again which would cause a performance issue if in large application?
You usually put Observables to subscribe to inside a Service and make them available via getters and setters.
When subscribing to an Observable it behaves in a certain way like an EventListener. Whenever the object inside the Observable gets changed, an Event gets fired and your code inside the subscription gets executed. Additionally, you get provided the updated object.
Even if you init the subscription inside ngOnInit this won't cause your entire Component to reload when an update arrives. Only those parts that get updated by your code inside the subscription.
You don‘t have to put a subscription inside ngOnInit(). It depends on what you want to achieve in the component. But most of the time you want to load and display data directly when you access the component and update the UI when this data changes. That's why it is good practice to put the subscription in ngOnInit().