This gist provides a useAsyncComputed function which allows to create asynchronous dependencies on reactive values (using Vue 3's Composition API).
Requires at least Vue 3.0 and TypeScript 4.0.
import { ref } from 'vue'
import useAsyncComputed from './use-async-computed'
const packageName = ref('color-blend')
function getDownloads() {
return fetch(`https://api.npmjs.org/downloads/point/last-week/${packageName.value}`)
.then(response => response.json())
.then(result => result.downloads)
}
const [downloads] = useAsyncComputed(getDownloads, 0)Whenever packageName is updated, the downloads will stay the same until the returned computed promise resolves.
The second parameter passed to the useAsyncComputed function is optional. If provided, it is used as the initial value held by the computed ref until its first evaluation resolves.
The return value of useAsyncComputed is a two-item tuple. While the first item holds the ref containing the latest evaluation result, the second item is a boolean ref which tells whether the computed ref is currently being (re-)evaluated.
const [downloads, isGettingDownloads] = useAsyncComputed(getDownloads, 0)This may be used for displaying a loading indicator instead of the stale downloads value when the packageName changes.
The asyny computed callback receives an onCancel function as its first argument. It can be invoked with a callback which will be executed when a re-evaluation of the async computed value is triggered before the current has finished.
This can be used to clean up resources used for evaluation, e.g. we could cancel fetch requests to the npm API by adjusting our getDownloads function from the introductory example:
function getDownloads(onCancel) {
const abortController = new AbortController()
onCancel(() => {
abortController.abort()
})
return fetch(`https://api.npmjs.org/downloads/point/last-week/${packageName.value}`, {
signal: abortController.signal
})
.then(response => response.json())
.then(result => result.downloads)
}-
Just like Vue's built-in
computedfunction,useAsyncComputeddoes dependency tracking and is automatically re-evaluated when dependencies change.Note however that only dependencies referenced in the first call stack are considered for this. In other words: Dependencies which are accessed asynchronously are not triggering re-evaluation of the async computed value.
-
As opposed to Vue's built-in
computedfunction, re-evaluation of the async computed value is triggered whenever dependencies are changing, regardless whether its result is being used or not.
@shaokeyibb Nowadays I'd recommend to use VueUse instead though. It has all the utilities you could wish for in Vue, and its
computedAsyncfunction is actually stemming from this Gist. π