Chào anh em, hôm nay mình sẽ chia sẻ cách anh em có thể debounce các request đến một endpoint cụ thể khi dùng Axios. Nếu anh em đã từng gặp trường hợp một endpoint bị gọi liên tục, dẫn đến việc server bị quá tải hoặc trả về lỗi, thì debounce chính là giải pháp.

Debounce giúp chúng ta chỉ gửi một request sau một khoảng thời gian nhất định, ngay cả khi hàm bị gọi liên tục. Hôm nay mình sẽ hướng dẫn anh em cách debounce một specific URL với Axios.


Cài đặt môi trường


Trước hết, anh em cần cài đặt thư viện lodash, vì mình sẽ dùng hàm debounce từ lodash để thực hiện yêu cầu này.


npm install lodash


Tạo một Axios Client với Interceptor


Ở đây, mình sẽ tạo một Axios client có interceptor để xử lý mọi request đi qua. Chúng ta sẽ kiểm tra URL của request, và nếu đúng là URL cần debounce, mình sẽ áp dụng cơ chế debounce cho nó.


Bước 1: Tạo một hàm debounced


Trước hết, mình cần tạo một hàm debounced bên ngoài interceptor để đảm bảo hàm này không bị tạo lại nhiều lần. Sử dụng lodash.debounce, mình sẽ trì hoãn việc gọi request trong một khoảng thời gian (ở đây mình chọn là 2 giây).


import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
import { debounce } from 'lodash';

// Khởi tạo axios client
const axiosClient = axios.create({
  baseURL: 'https://your-api.com',
  headers: {
    'Content-Type': 'application/json',
    'Access-Control-Allow-Origin': '*',
  },
});

// URL endpoint cần debounce
const DEBOUNCED_URL = '/specific-endpoint';

// Tạo một hàm debounced
const debouncedRequest = debounce((resolve, config) => {
  resolve(config); // Sau khi hết thời gian debounce, sẽ resolve request
}, 2000); // 2000ms debounce delay


Bước 2: Sử dụng Axios Interceptor


Interceptor cho phép anh em kiểm soát toàn bộ các request trước khi nó được gửi đi. Ở đây, mình sẽ kiểm tra URL của request, và nếu URL này trùng với URL cần debounce (DEBOUNCED_URL), thì mình sẽ gọi hàm debouncedRequest.


axiosClient.interceptors.request.use(
  function (config: AxiosRequestConfig) {
    // Kiểm tra xem URL có phải là endpoint cần debounce hay không
    if (config.url?.includes(DEBOUNCED_URL)) {
      return new Promise((resolve) => {
        console.log('Request được debounce');
        debouncedRequest(resolve, config); // Gọi hàm debounce
      });
    }
    return config; // Các URL khác thì cứ request bình thường
  },
  function (error) {
    return Promise.reject(error);
  }
);


Bước 3: Xử lý response


Anh em cũng có thể thêm một interceptor cho response để xử lý dữ liệu trả về hoặc các lỗi trong quá trình gọi request.


axiosClient.interceptors.response.use(
  function (response: AxiosResponse) {
    return response.data; // Trả về dữ liệu nếu thành công
  },
  function (error) {
    console.error('Error:', error); // Log lỗi nếu có vấn đề
    return Promise.reject(error);
  }
);


Tổng kết


Vậy là xong! Giờ đây, mỗi khi anh em gọi request đến /specific-endpoint, nó sẽ được debounce, nghĩa là chỉ một request sẽ được gửi sau mỗi 2 giây, ngay cả khi anh em gọi nhiều lần liên tục.


Anh em có thể điều chỉnh thời gian debounce theo nhu cầu bằng cách thay đổi giá trị 2000 (tính bằng mili giây). Hy vọng cách này sẽ giúp anh em tối ưu việc gọi API và tránh những vấn đề không đáng có với server.


Chúc anh em code vui và hiệu quả! 😄


Gavin Nguyen!