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.