debounce, throttle và once - ba hàm thêm cách giải quyết logic người dùng!

debounce, throttle và once - ba hàm thêm cách giải quyết logic người dùng!

Tin ngắn hàng ngày dành cho bạn
  • Mấy hôm trước OpenAI giới thiệu Deep Research - một công cụ duyệt web để nghiên cứu và cho ra một bản tổng hợp chỉ trong vài chục phút - so với nhiều giờ làm việc đối với con người, theo như họ công bố.

    Tính năng này hiện chỉ có sẵn cho người dùng Pro. Mặc dù chưa được dùng thử, nhưng qua nhiều bài viết đều nhấn mạnh vào sự ấn tượng trước khả năng của công cụ mới này. Nếu vẫn chưa biết Deep Research làm được gì thì bạn cứ hình dung như thế này: Nói với nó "Tôi cần thông tin nghiên cứu về lượng tiêu thụ cà phê của thế giới trong năm ngoái". Thế thôi! Ngồi chờ một lúc để nó tìm kiếm và tổng hợp lại kết quả và gửi lại cho bạn một bài báo cáo chi tiết. Chà, ghê thật chứ!

    Ngay lập tức huggingface đã lên một bài viết cố gắng tái tạo lại công cụ này theo cách của họ. Chi tiết tại Open-source DeepResearch – Freeing our search agents. Và không có gì ngạc nhiên khi cả 2 đều mang hơi hướng của AI Agents.

    » Xem thêm
  • Sống đủ lâu trong thế giới Internet, bạn có thể thấy rằng mọi người ở đây khá háo hức chạy theo xu hướng và chúng lan truyền với tốc độ chóng mặt.

    Chỉ vài tháng trước, chúng ta vẫn còn kinh ngạc về trí thông minh của các mô hình ngôn ngữ lớn (LLM) có thể trả lời giống như con người, và ngay sau đó, chúng đã được cập nhật với khả năng suy nghĩ và lý luận đáng kinh ngạc. Chúng được ứng dụng rộng rãi không chỉ trong lĩnh vực lập trình. Gần đây, thuật ngữ AI Agents đã tạo nên một sự khuấy động.

    Vậy, AI Agents là gì? Trong bài viết ngắn này, tất nhiên là không thể đưa ra một định nghĩa ngắn gọn nhưng toàn diện. Bạn đọc có thể tham khảo bài viết rất chi tiết này tại đây Agents | Chip Huyền. Để dễ hình dung hơn, AI Agents có thể được coi là một người hoặc một thực thể nào đó. Bản thân các Agents được trang bị tất cả các công cụ cần thiết. Từ đó, các Agents có thể kết hợp chúng để hoàn thành một nhiệm vụ mà chúng ta giao.

    Vẫn còn hơi mơ hồ phải không? Một ví dụ thực tế là khi bạn ra lệnh cho các Agents truy cập Facebook vào lúc 8 giờ tối mỗi ngày, kiểm tra bất kỳ tin tức nổi bật nào từ bạn bè, sau đó gửi tóm tắt đến Telegram. Vậy là xong!

    » Xem thêm
  • Hôm qua đến nay, lượt truy cập tới từ Facebook tăng đột biến. Thường như thế là do ai đó chia sẻ bài viết của blog vào một nhóm nào đó.

    Cơ mà lần này là liên kết trực tiếp đến trang chủ luôn. Tò mò ghê, không biết ai chia sẻ, chia sẻ ở đâu nữa. Muốn biết để tìm hiểu "insight" ghê 🥹

    » Xem thêm

Vấn đề

Tìm ra cách giải quyết vấn đề là một trong những kỹ năng hết sức quan trọng đối với lập trình viên. Thông thường, khi chúng ta làm càng nhiều thì kinh nghiệm càng lên cao. Lúc này đối mặt với những bài toán tương tự mà có thể nhanh chóng tìm ra hướng giải quyết.

Có nhiều cách để học hỏi kinh nghiệm, một trong số đó là chịu khó tìm kiếm và đọc nhiều bài viết, tài liệu trên mạng. Nhiều khi kiến thức ta thu nạp được chưa cần thiết ngay lúc này, nhưng đến một lúc nào đó nó có thể phát huy tác dụng. Hoặc ít ra, đọc để trong đầu ta tự thốt lên: "À hóa ra với trường hợp này thì chúng ta nên xử lý thế này...".

debonce, throttleonce là ba hàm tiện ích mà qua đó có thể ứng dụng trong rất nhiều trường hợp. Đặc biệt là logic về UI/UX, trải nghiệm người dùng... Bài viết ngày hôm nay, tôi xin phép được trình bày về công dụng cũng như cách sử dụng chúng.

Debounce

Debounce là một kỹ thuật ngăn chặn một chuỗi sự kiện tương tự nhau diễn ra liên tiếp. Thay vào đó, sự kiện tiếp theo chỉ được gọi sau một khoảng thời gian hành động chấm dứt.

Một ví dụ thông dụng nhất mà chúng ta thường gặp đó là tính năng gõ từ khóa vào ô tìm kiếm. Khi nhập kí tự, kết quả tìm kiếm hoặc cụm từ gợi ý hiện ra. Đằng sau quá trình này là một cách xử lý nào đó, ví dụ như gọi API để lấy dữ liệu trước khi người dùng bấm vào nút tìm kiếm hoặc nhấn Enter. Nếu bắt sự kiện keypress thì cứ mỗi lần nhấn phím sẽ gọi một lần API. Như thế quả là lãng phí tài nguyên máy chủ bời vì tốc độ của người gõ là rất nhanh, chưa kể từ khóa họ nhập vào còn chưa đầy đủ. Để xử lý tối ưu trong trường hợp này là chờ một khoảng thời gian người dùng không nhấn nhím nữa thì hãy kích hoạt cuộc gọi API.

Đây là lúc debounce phát huy tác dụng. Một hàm debounce có thể trông giống như dưới đây:

function debounce(func, delay) {
  let timeout;
  return function() {
    const context = this;
    const args = arguments;
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(context, args), delay);
  };
}

Sau đó, sử dụng hàm trong sự kiện keypress. Ở đây mình lấy ví dụ trong vue:

<input @keypress="debounce(triggerCallAPI, 500)" />

Khi đó cứ mỗi 500ms mà người dùng không nhập gì nữa thì triggerCallAPI sẽ được gọi.

Một trường hợp phổ biến khác là sự kiện resize của trình duyệt. Trong quá trình thay đổi kích thước cửa sổ, có nhiều hàm cần chạy để xử lý logic. Nếu cứ gọi hàm liên tục khi resize chắc chắn hiệu năng sẽ bị ảnh hưởng. Lúc đó, chúng ta có thể sử dụng debounce để giải quyết vấn đề này.

Throttle

Throttle phần nào giống như Debounce. Nghĩa là nó cũng ngăn chặn sự kiện diễn ra liên tiếp, nhưng theo một cách khác so với Debounce.

Nếu Debounce chỉ kích hoạt sự kiện sau một khoảng thời gian mà sự kiện không xảy ra nữa thì Throttle lại chỉ kích hoạt sự kiện sau một khoảng thời gian mà bất kể sự kiện đó có diễn ra hay không. Hay nói ngắn gọn lại là Throttle chỉ cho phép chạy một sự kiện trong mỗi x giây. Sau x giây, lần chạy tiếp theo mới được thực thi nếu nó còn được kích hoạt (trigger).

Một hàm throttle có thể trông giống như dưới đây:

function throttle(func, delay) {
  let wait = false;

  return (...args) => {
    if (wait) {
        return;
    }

    func(...args);
    wait = true;
    setTimeout(() => {
      wait = false;
    }, delay);
  }
}

Bất cứ khi nào cần giới hạn thời gian giữa các lần kích hoạt sự kiện bạn có thể áp dụng Throttle. Ví dụ, ngăn chặn người dùng bấm quá nhanh vào một nút "Submit".

<input type="submit" @submit="throttle(triggerCallAPI, 500)" />

Nghĩa là triggerCallAPI chỉ được gọi sau mỗi 500ms bất kể người dùng có bấm vào nút bao nhiêu lần đi chăng nữa.

Once

Once chỉ cho phép sự kiện được gọi một lần duy nhất. Once hữu ích trong trường hợp bạn chỉ cho phép người dùng thực hiện một hành động trong phiên truy cập.

Một hàm once có thể giống giống như sau:

function once(func) {
  let ran = false;
  let result;
  return function() {
    if (ran) return result;
    result = func.apply(this, arguments);
    ran = true;
    return result;
  };
}

Ví dụ sử dụng trong trường hợp nút "Đánh dấu tất cả là đã đọc" của khung thông báo. Người dùng chỉ cần thực hiện bấm vào nút đó một lần trong mỗi phiên.

<button @click="once(triggerCallAPI)">Đánh dấu tất cả là đã đọc</button>

triggerCallAPI chỉ được gọi một lần duy nhất khi người dùng bấm vào button. Các lần tiếp theo, triggerCallAPI sẽ không được kích hoạt.

Tổng kết

Trên đây là 3 hàm debounce, throttleonce với mô tả kèm theo cách sử dụng. Chúng rất thông dụng trong xử lý logic về giao diện người dùng, đến nỗi nhiều thư viện tiện ích đều có mặt của 3 hàm này như là lodash. Việc biết đến cũng như biết cách sử dụng có thể giúp bạn giảm được thời gian giải quyết vấn đề trong những trường hợp tương tự trong bài viết.

Tài liệu tham khảo:

Cao cấp
Hello

5 bài học sâu sắc

Mỗi sản phẩm đi kèm với những câu chuyện. Thành công của người khác là nguồn cảm hứng cho nhiều người theo sau. 5 bài học rút ra được đã thay đổi con người tôi mãi mãi. Còn bạn? Hãy bấm vào ngay!

Mỗi sản phẩm đi kèm với những câu chuyện. Thành công của người khác là nguồn cảm hứng cho nhiều người theo sau. 5 bài học rút ra được đã thay đổi con người tôi mãi mãi. Còn bạn? Hãy bấm vào ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.

Bình luận (0)

Nội dung bình luận...
Bấm hoặc cuộn mạnh để sang bài mới