takeaway
When we read the source code, we often have a lot of questions, such as, why is the code here written this way?
When we have a problem, how can we test our guesses if we are not sure if they are correct?
Let me use an example to illustrate
What’s my guess
The options flush parameter of watch (link to documentation) corresponds to different execution timing of Effect (before, during, after component update).
But from looking at the source code, before and after divided into three execution queue, and the three execution queue is synchronous execution, there is no asynchronous in the middle, are in this part of the code in the same execution stack
So I guess: Flush: post, watch callback is executed after component update and before rendering
Vue Scheduler scheduler scheduler scheduler scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler Scheduler
function flushJobs() {
/ /...
// Queue before performing component data update
flushPreFlushCbs(seen)
/ /...
try {
// Execute component data update queue
for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {
const job = queue[flushIndex]
if(job && job.active ! = =false) {
callWithErrorHandling(job, null, ErrorCodes.SCHEDULER)
}
}
} finally {
/ /...
// Queue after component data update
flushPostFlushCbs(seen)
/ /...}}Copy the code
There are three queues, respectively before, during, and after component data update.
The easiest way to test my guess is to write a simple demo and debug it yourself. If you don’t know how to debug VUE3, please refer to this article
Write a validated demo
To determine if the watch callback is executed flush: POST after the component is updated and before rendering, we need to stop the code in the Watch callback and check the interface for changes
If the interface is not updated when it stops, the Watch Callback is executed before rendering
How do I stop code in callback? Use the debugger?
This is a very error-prone point, and it’s very hidden. The debugger can trigger chrome breakpoint debugging to stop js code execution, but it doesn’t stop rendering!
Because the rendering doesn’t stop, the debugger causes the interface to update, which results in the exact opposite result!
Therefore, it is very important to verify the correctness of the method! Otherwise you might get the exact opposite result!
To stop both js and render, we can use alert
So we can write the following validation code, in the watch callback, add an alert line.
<! DOCTYPEhtml>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width = device - width, initial - scale = 1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<title>Document</title>
<script src='.. /vue/dist/vue.global.js'></script>
</head>
<body>
<div id='app'>
</div>
<script>
const App = {
template: ` {{ name }}
`.setup() {
const name = Vue.ref('vue setup')
Vue.watch(name, () = > {
console.log('watch post', name.value)
alert()
debugger
}, {
flush: 'post'
})
setTimeout(() = > {
name.value = 'vue mounted change'
}, 3000)
return {
name
}
}
}
let vm = Vue.createApp(App).mount('#app')
</script>
</body>
</html>
Copy the code
The results
As I suspected, when Flush: POST, watch Callback is executed before component data is updated and UI rendered
conclusion
When reading the source code, it is often not very smooth, but also requires some patience. When you encounter problems, you need some methodology to try to understand and solve them.
First put forward the conjecture, and then do demo verification, deepen the understanding.
Sometimes the guess may not be correct, or it may be that the guess is correct, but the validation method is incorrect (as if the debugger was used to stop the code), leading to the opposite conclusion. This is when we need to be patient and deliberate.
By the end, we’ll have a better understanding of the source code.