'Compiled Runtime Ordering of Watchers in Vue 3

So, let's hypothetically say I have the following setup:

<script setup lang="ts">
const someRef = ref<null | string>(null)

const setSomeRef = (v: string) => {
    someRef.value = v
}

const watcher1 = watch(someRef, () => {
    doSomething()
})

const watcher2 = watch(someRef, () => {
    doSomethingElse()
})
</script>
<template>
    <button @click="setSomeRef("Hello!")">Hit Me!</button>
</template>

Let's also just hypothetically imagine that these two watchers might be in two different composables, but maybe instantiated on the same component ... for reasons.

A user clicks the button.

My thought is, which function fires first? doSomething() or `doSomethingElse()?

Do they always fire in the same order? ... and does it matter if the side effects are unrelated, i.e., is the perceived difference negligible?



Solution 1:[1]

Seems like this should not be a concern in JavaScript. And you are proberbly doing something wrong, if you need this. You need more control and predictability than this.

I did a very small test, that might help you. Seems like the code runs synchronous (as expected in JavaScript) with less than .3 milliseconds in between (on my machine).

Test in Playground

<script setup lang="ts">
import {ref, watch} from 'vue'
const test = ref([])
const someRef = ref(0)
const setSomeRef = () => {
    someRef.value++
}
const watcher1 = watch(someRef, () => {
  test.value.push("1: " + window.performance.now())
    console.log("1: ", window.performance.now())
})
const watcher2 = watch(someRef, () => {
    test.value.push("2: " + window.performance.now())
    console.log("2: ", window.performance.now())
})
</script>

<template>
  <button @click="setSomeRef()">Hit Me!</button>
  <div v-for="i in test">
    {{i}}
  </div>
</template>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 tauzN