I use Vue and have a method in load.js.
async function loadTask(x) {
return await x; // Some async code
}
export { loadTask };
In a Vue component I call it but the await prevent the <template> to load. Without the await, the code below runs. What do I miss?
<script setup>
import { loadTask } from './methods/load.js';
const test = loadTask(3);
console.log(await test);
</script>
<template>
<div>Does not run</div>
</template>
According to the documentation:
async setup() must be used in combination with Suspense, which is currently still an experimental feature. We plan to finalize and document it in a future release - but if you are curious now, you can refer to its tests (opens new window)to see how it works.
https://v3.vuejs.org/api/sfc-script-setup.html#top-level-await
https://v3.vuejs.org/guide/migration/suspense.html#suspense
Vue <script setup> Top level await causing template not to render
So if you have async setup you have to import this component in parent like that:
import { defineAsyncComponent } from "vue";
export default {
components: {
HelloWorld: defineAsyncComponent(() =>
import("./components/HelloWorld.vue")
),
},
};
</script>
And use it in template wrapped in suspense:
<template>
<suspense>
<template #default>
<HelloWorld />
</template>
<template #fallback>
<div>Loading...</div>
</template>
</suspense>
</template>
Demo:
https://codesandbox.io/s/reverent-sinoussi-9r5or?file=/src/components/HelloWorld.vue
As described in Vue <script setup> Top level await causing template not to render,
in case you don't need the full power of async components and Suspense, you can use either onBeforeMount:
const test = ref('');
onBeforeMount(async () => {
test.value = await loadTask(3);
console.log(test.value);
})
or do the initialization inside an async function that you invoke without awaiting for the promise to complete:
const test = ref('');
const init = async () => {
test.value = await loadTask(3);
console.log(test.value);
}
init();
or use promise chainig:
const test = ref('');
loadTask(3).then(task => {
test.value = task;
console.log(test.value);
});
You additionally need to take care of error handling as appropriate for each case.