javascript / intermediate
Snippet
Aborting Stale Asynchronous Fetch Requests Inside Vue Watchers
Rapid state changes in reactive watchers can cause race conditions where outdated async responses overwrite newer query results. Passing an AbortController signal to fetch and registering its abort invocation via onCleanup ensures in-flight requests are immediately terminated before subsequent triggers run, while filtering AbortError prevents false error notifications.
snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import { ref, watch } from 'vue';export function useLiveSearch(queryRef: ReturnType<typeof ref<string>>) {const results = ref<string[]>([]);const isSearching = ref(false);const searchError = ref<Error | null>(null);watch(queryRef, async (query, _, onCleanup) => {if (!query.trim()) {results.value = [];return;}const controller = new AbortController();onCleanup(() => controller.abort());isSearching.value = true;searchError.value = null;try {const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`, {signal: controller.signal});if (!response.ok) throw new Error(`HTTP Error: ${response.status}`);results.value = await response.json();} catch (err: unknown) {if (err instanceof DOMException && err.name === 'AbortError') return;searchError.value = err instanceof Error ? err : new Error(String(err));} finally {if (!controller.signal.aborted) isSearching.value = false;}});return { results, isSearching, searchError };}
vue
Breakdown
1
watch(queryRef, async (query, _, onCleanup) => {
Receives the onCleanup registration hook from Vue's watch API alongside the updated query string.
2
onCleanup(() => controller.abort());
Registers a cancellation hook executed immediately whenever the watcher re-evaluates or unmounts.
3
signal: controller.signal
Binds the fetch operation directly to the abort signal lifecycle.
4
if (err instanceof DOMException && err.name === 'AbortError') return;
Catches and ignores expected cancellation errors to prevent displaying false-positive UI alerts.