Svelte Script Code Execution Order
Tags: svelte, javascript, webdev, programming
Published: 2022-11-25 09:34:48

While working on my first Svelte project for a [Wunderdog](https://www.wunderdog.fi) customer, I was caught by surprise—not by Svelte being very effective and fun to work with, that part I already knew. 

What surprised me was the order in which Svelte was executing JavaScript code, especially when mixing up asynchronous functions, reactive statements, and onMount.

For example, take a look at this Svelte component, or head to the [Svelte REPL](https://svelte.dev/repl/6e42003c562b4be19ddd8bbfcdbb9d2f?version=3.53.1). In which order will these console logs appear? Go ahead and write it down before you continue reading. 

```html
<script>
  import { onMount } from 'svelte'
	
  const fetchData = async () => {
    console.log('1. fetchData')
  }
	
  console.log('2. started')
	
  fetchData().then(() => console.log('3. fetched'))
	
  $: console.log('4. reactive')
	
  console.log('5. continued')
	
  onMount(() => {
    console.log('6. onMount')
  })
	
  console.log('7. after mount')
</script>
```

## The Answer

`2. started`
`1. fetchData`
`5. continued`
`7. after mount`
`4. reactive`
`6. onMount`
`3. fetched`

## Why is that? Let’s investigate

### 2. started

The `fetchData` constant is assigned to an asynchronous function. The function isn’t called yet, so it doesn’t log anything at the moment. Hence, the first log that appears in the console is `2. started`.

### 1. fetchData

Next, the `fetchData` function is called, thus `1. fetchData` is logged to the console. The callback `.then(() => console.log('3. fetched'))` isn’t called just yet—it’s added to the browser’s message queue, and will be called once the event loop reaches it, a bit later.

### 5. continued

Shouldn’t `4. reactive` be logged now? That’s what I thought, but turns out I was wrong. According to the [Svelte docs](https://svelte.dev/docs#component-format-script-3-$-marks-a-statement-as-reactive):

> Reactive statements run after other script code and before the component markup is rendered, whenever the values that they depend on have changed.

Indeed, other script code hasn’t finished running yet. Therefore, this reactive statement isn’t executed at this time, and the next console log is `5. continued`.

### 7. after mount

`7. after mount` is logged to the console. That’s because the callback in `onMount` will only be called once the component is first rendered, and that hasn’t happened yet.

### 4. reactive

Now we hit that sweet spot after other script code has been executed, and before the component markup is rendered. This means it’s time to execute that reactive statement, thus logging `4. reactive` to the console.

### 6. onMount

At this point there is no more script code to execute and the component is rendered. Thus, the `onMount` callback is called and `6. onMount` is logged to the console.

### 3. fetched

What about the callback to our asynchronous function, remember that? Oh yeah, says the event loop, as it handles the message queue. The callback is executed, and finally, `3. fetched` is logged to the console.

## Done

While I find Svelte to be very intuitive and developer friendly, the script execution order can be a bit puzzling when using asynchronous functions and reactive statements. I hope that this post has helped you to understand this issue and to squash your bugs.

_Photo by <a href="https://unsplash.com/@cookiethepom?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Cookie the Pom</a> on <a href="https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>_