Preventing Duplicate API Requests in Front‑end Development with Debounce, Throttle, Loading Locks, and Axios CancelToken
The article explains why repeated button clicks or searches cause duplicate API calls, discusses why debounce/throttle are not ideal, and presents three practical solutions—loading state locking, request cancellation with Axios CancelToken, and related code examples—to efficiently avoid redundant requests in Vue applications.
In everyday front‑end development, clicking a button or performing a search often triggers an API request; repeated clicks without optimization lead to duplicate requests, wasting performance and causing bugs when the interface response is slow.
The article first mentions the traditional debounce/throttle approach, noting it is not recommended for this scenario, and provides Vue code examples for both techniques.
Debounce implementation:
<template>
<div>
<button @click="debouncedFetchData">请求</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import axios from 'axios';
const timeoutId = ref(null);
function debounce(fn, delay) {
return function(...args) {
if (timeoutId.value) clearTimeout(timeoutId.value);
timeoutId.value = setTimeout(() => { fn(...args); }, delay);
};
}
function fetchData() {
axios.get('http://api/gcshi')
.then(response => { console.log(response.data); });
}
const debouncedFetchData = debounce(fetchData, 300);
</script>Throttle implementation:
<template>
<div>
<button @click="throttledFetchData">请求</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import axios from 'axios';
const lastCall = ref(0);
function throttle(fn, delay) {
return function(...args) {
const now = new Date().getTime();
if (now - lastCall.value < delay) return;
lastCall.value = now;
fn(...args);
};
}
function fetchData() {
axios.get('http://api/gcshi')
.then(response => { console.log(response.data); });
}
const throttledFetchData = throttle(fetchData, 1000);
</script>Because debounce and throttle add unnecessary complexity here, the article recommends simpler methods.
Loading‑state lock: Set a loading flag before sending a request; if the flag is true, subsequent clicks are ignored. The Vue example shows how to implement this lock.
<template>
<div>
<button @click="fetchData">请求</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import axios from 'axios';
const loading = ref(false);
function fetchData() {
if (loading.value) return;
loading.value = true;
axios.get('http://api/gcshi')
.then(response => { console.log(response.data); })
.finally(() => { loading.value = false; });
}
</script>While straightforward, this method cannot cancel an ongoing request, so a new request (e.g., a second search) must wait for the first to finish.
Axios CancelToken cancellation: Axios provides built‑in cancellation. By storing a CancelToken.source() and calling source.cancel() before a new request, duplicate calls are aborted. The article includes a Vue example and notes that the same token or an AbortController signal can cancel multiple requests.
<template>
<div>
<button @click="fetchData">请求</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import axios from 'axios';
let cancelTokenSource = null;
function fetchData() {
if (cancelTokenSource) {
cancelTokenSource.cancel('Cancel previous request');
cancelTokenSource = null;
}
cancelTokenSource = axios.CancelToken.source();
axios.get('http://api/gcshi', { cancelToken: cancelTokenSource.token })
.then(response => { console.log(response.data); })
.catch(err => { if (axios.isCancel(err)) console.log('Request canceled'); });
}
</script>The article also references the official Axios cancellation documentation and shows an alternative using AbortController alongside CancelToken for broader compatibility.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.