setTimeout(): Hẹn giờ code, chill thôi không vội!
Nodejs

setTimeout(): Hẹn giờ code, chill thôi không vội!

Author

Admin System

@root

Ngày xuất bản

21 Mar, 2026

Lượt xem

4 Lượt

"timers.setTimeout()"

Chào các thần dân tương lai của đế chế code! Anh Creyt đây, và hôm nay chúng ta sẽ cùng nhau khám phá một 'siêu năng lực' mà bất cứ developer nào cũng cần phải nắm vững: timers.setTimeout(). Nghe tên thì có vẻ học thuật, nhưng thực ra nó chỉ là cái 'hẹn giờ' của code mình thôi, đơn giản như việc em đặt báo thức để dậy đi học hay hẹn giờ nấu mì vậy. Chill lắm!

1. timers.setTimeout() là gì và để làm gì? – Kẻ Trì Hoãn Bất Đắc Dĩ, Nhưng Lại Cực Kỳ Hữu Dụng!

Trong thế giới Node.js (và cả JavaScript nói chung), setTimeout() là một hàm cho phép em thực thi một đoạn code (hay còn gọi là một "callback function") sau một khoảng thời gian nhất định. Cứ hình dung thế này: em đưa cho thằng bạn một tờ giấy ghi "30 phút nữa thì mày gọi điện cho tao nhé", xong em cứ làm việc của em, không cần đứng đó chờ nó gọi. Đúng 30 phút, nó sẽ gọi. Thằng bạn đó chính là setTimeout(), còn em thì cứ "chill" mà làm việc khác.

Điểm cực kỳ quan trọng ở đây là tính bất đồng bộ (asynchronous) của nó. Tức là, khi em gọi setTimeout(), Node.js sẽ "đặt lịch" cho đoạn code đó, nhưng nó sẽ không dừng lại để chờ đợi. Nó sẽ tiếp tục thực thi các dòng code tiếp theo ngay lập tức. Đây chính là lý do Node.js có thể xử lý nhiều tác vụ cùng lúc mà không bị "treo" máy.

Để làm gì ư? Đa năng lắm em ơi:

  • Trì hoãn hành động: Chờ 5 giây rồi mới hiển thị thông báo, hoặc sau 10 giây mới chuyển hướng trang.
  • Tạo hiệu ứng UI/UX: Hiển thị một loader (vòng quay chờ) trong 2 giây rồi mới ẩn đi, tạo cảm giác mượt mà hơn.
  • Debouncing/Throttling: Cái này hay nè! Em gõ vào ô tìm kiếm, thay vì cứ mỗi ký tự gõ vào là gửi request lên server, mình sẽ chờ user ngừng gõ khoảng 300ms rồi mới gửi. Tránh "spam" server. (Anh sẽ nói kỹ hơn về cái này sau).
  • Lên lịch các tác vụ nhẹ: Đôi khi mình cần một tác vụ chạy sau một chút để đảm bảo các tác vụ khác đã hoàn thành.

2. Code Ví Dụ Minh Hoạ – Tự Tay "Hẹn Giờ"!

Sẽ chẳng có ý nghĩa gì nếu không có code thực chiến, đúng không? Cùng xem vài ví dụ kinh điển nhé!

Ví dụ 1: Hẹn giờ đơn giản nhất

console.log('Bắt đầu công việc...');

setTimeout(() => {
  console.log('Công việc này được thực hiện sau 2 giây. Hẹn giờ xong!');
}, 2000); // 2000 milliseconds = 2 giây

console.log('Trong lúc chờ đợi, tôi vẫn làm việc khác...');

Kết quả:

Bắt đầu công việc...
Trong lúc chờ đợi, tôi vẫn làm việc khác...
Công việc này được thực hiện sau 2 giây. Hẹn giờ xong!

Thấy chưa? Dòng code console.log('Trong lúc chờ đợi...') chạy ngay lập tức, không thèm đợi cái setTimeout kia!

Ví dụ 2: Hủy hẹn giờ với clearTimeout()

Đôi khi mình đặt hẹn giờ, nhưng sau đó lại đổi ý và muốn hủy nó đi. clearTimeout() sinh ra là để làm điều đó.

console.log('Chuẩn bị kích hoạt bom sau 5 giây...');

const bombTimer = setTimeout(() => {
  console.log('BÙMMMM! Bom đã nổ!');
}, 5000);

// Giả sử sau 2 giây, chúng ta tìm được cách gỡ bom
setTimeout(() => {
  console.log('Gỡ bom thành công! Hủy kích hoạt!');
  clearTimeout(bombTimer); // Hủy hẹn giờ nổ bom
}, 2000);

console.log('Đang tìm cách gỡ bom...');

Kết quả:

Chuẩn bị kích hoạt bom sau 5 giây...
Đang tìm cách gỡ bom...
Gỡ bom thành công! Hủy kích hoạt!

May mắn là bom không nổ! clearTimeout() nhận vào ID mà setTimeout() trả về để biết phải hủy cái hẹn giờ nào.

Ví dụ 3: Truyền tham số vào callback

Đôi khi hàm callback của em cần dữ liệu từ bên ngoài. Có hai cách:

  • Sử dụng Closure: (Cách phổ biến và khuyến nghị)
const userName = 'Creyt';
const message = 'Hãy học hành chăm chỉ!';

setTimeout(() => {
  console.log(`Chào ${userName}, ${message}`);
}, 1000);
  • Truyền trực tiếp (ít dùng hơn trong Node.js, phổ biến trong browser JS cũ):
function greet(name, msg) {
  console.log(`Chào ${name}, ${msg}`);
}

// Các đối số sau thời gian delay sẽ được truyền vào hàm greet
setTimeout(greet, 1000, 'Anh Creyt', 'Hãy tiếp tục cố gắng!');
Illustration

3. Mẹo (Best Practices) để ghi nhớ và dùng thực tế – "Bí Kíp Luyện Rồng"!

  • Hiểu rõ this context: Khi dùng function() {} truyền thống làm callback, this bên trong nó có thể không phải là cái em mong muốn (thường là global object trong Node.js hoặc window trong browser). Luôn dùng arrow function () => {} để tránh đau đầu về this vì nó giữ this của ngữ cảnh bên ngoài.
  • Luôn clearTimeout() khi không cần nữa: Đặc biệt trong các ứng dụng web phức tạp, nếu em tạo setTimeout mà không hủy khi component bị unmount hoặc sự kiện kết thúc, nó có thể dẫn đến memory leak hoặc các hành vi không mong muốn. Cứ như việc em đặt báo thức mà không tắt đi, nó cứ kêu mãi vậy!
  • setTimeout vs setInterval: setTimeout chạy một lần duy nhất. setInterval thì chạy lặp đi lặp lại. Đừng nhầm lẫn! Nếu muốn lặp, hãy dùng setInterval hoặc lồng setTimeout một cách có kiểm soát (nhưng anh Creyt khuyến nghị setInterval cho các tác vụ lặp đều đặn).
  • Độ chính xác thời gian: Thời gian delay trong setTimeout không đảm bảo chính xác tuyệt đối. Nó chỉ là thời gian tối thiểu trước khi callback được đưa vào Event Loop queue. Nếu Event Loop đang bận xử lý tác vụ nặng khác, callback của em có thể bị trì hoãn thêm một chút. Đừng dùng nó cho những tác vụ đòi hỏi độ chính xác miligiây tuyệt đối nhé!
  • Tránh "Callback Hell" với setTimeout: Đừng lồng quá nhiều setTimeout vào nhau, nó sẽ thành một mê cung code khó đọc, khó debug. Nếu cần tuần tự các tác vụ bất đồng bộ, hãy nghĩ đến Promises hoặc async/await.

4. Văn phong học thuật sâu của anh Creyt – Sân khấu của Event Loop!

Để hiểu tại sao setTimeout lại bất đồng bộ và không chặn luồng chính, chúng ta cần nói qua về "Event Loop" trong Node.js. Cứ hình dung Node.js như một nhà hàng chỉ có một đầu bếp chính (Main Thread), nhưng lại có rất nhiều nhân viên phục vụ, rửa bát, thu ngân (Worker Threads, I/O Threads, v.v.).

Khi em gọi setTimeout(), đầu bếp chính không tự mình đếm giây. Thay vào đó, anh ta viết một cái "phiếu hẹn giờ" và đưa cho một nhân viên khác (thường là một module C++ bên dưới, hoặc một phần của runtime) để quản lý. Khi thời gian hẹn giờ kết thúc, nhân viên đó sẽ đưa lại cái "phiếu" đã hết hạn vào một cái "khay chờ" (Callback Queue).

Đầu bếp chính (Event Loop) cứ liên tục kiểm tra xem có món nào đã xong chưa (tức là có callback nào trong Callback Queue không). Nếu có, anh ta sẽ lấy ra và xử lý. Chính vì thế, đầu bếp chính không bao giờ bị "treo" vì phải chờ đợi setTimeout đếm giờ, anh ta cứ làm các công việc khác cho đến khi có "phiếu" hết hạn được đưa vào khay chờ.

Đây chính là cốt lõi của tính bất đồng bộ, giúp Node.js xử lý hàng ngàn request cùng lúc mà không bị nghẽn cổ chai!

5. Ví dụ thực tế các ứng dụng/website đã ứng dụng – Hóa ra nó ở khắp nơi!

  • Facebook/Zalo/Slack: Khi bạn bè đang gõ tin nhắn, em thấy chữ "[Tên người dùng] is typing...". Đó chính là setTimeout đó! Khi user bắt đầu gõ, một setTimeout được kích hoạt. Nếu user gõ tiếp, setTimeout cũ bị hủy và cái mới được tạo. Nếu user dừng gõ (khoảng 1-2 giây), setTimeout sẽ chạy và ẩn dòng chữ "is typing..." đi.
  • Các trang thương mại điện tử (Shopee, Tiki, Lazada): Khi em gõ tìm kiếm sản phẩm, thay vì mỗi chữ gõ vào là nó lại gửi request lên server, thì nó sẽ dùng setTimeout để "debounce". Chỉ khi em ngừng gõ một khoảng thời gian ngắn (ví dụ 300ms), nó mới gửi request tìm kiếm thật sự. Giúp giảm tải cho server và tăng trải nghiệm người dùng.
  • Loading Screens & Notifications: Nhiều website hiển thị một spinner loading trong vài giây, hoặc một thông báo "Đăng nhập thành công!" tự động biến mất sau 3 giây. Đó đều là công việc của setTimeout.
  • Game Development (web-based): Kích hoạt một sự kiện trong game sau một khoảng thời gian nhất định, ví dụ: quả bom nổ sau 3 giây, hiệu ứng hồi máu sau 5 giây.
  • Retry Mechanisms: Nếu một API call bị lỗi tạm thời (ví dụ: server bận), ứng dụng có thể dùng setTimeout để thử lại (retry) sau một khoảng thời gian nhất định (ví dụ: 1 giây, 2 giây, 4 giây... theo cấp số nhân).

6. Thử nghiệm đã từng và hướng dẫn nên dùng cho case nào – Chia sẻ từ chiến trường!

Anh Creyt đã từng "flex" setTimeout trong nhiều dự án, từ nhỏ đến lớn:

  • Tạo Debounce cho API search: Hồi xưa, anh làm cái tính năng tìm kiếm sản phẩm, ban đầu cứ gõ một chữ là bắn API cái chát, server khóc thét! Sau đó anh dùng setTimeout để debounce, chỉ gọi API khi user ngừng gõ 500ms. Cả dev lẫn server đều "thở phào nhẹ nhõm".
  • Xây dựng cơ chế "Self-destruct message" cho ứng dụng chat nội bộ: Tức là tin nhắn tự động biến mất sau 10 giây. Anh dùng setTimeout để hẹn giờ xóa tin nhắn ở cả client và server, tạo cảm giác "điệp viên 007" cho anh em.
  • Xử lý các tác vụ "background" nhẹ: Đôi khi có những tác vụ không quá quan trọng, có thể chờ một chút để hệ thống ưu tiên các tác vụ chính trước. Anh sẽ dùng setTimeout(..., 0) (delay 0ms) để đẩy tác vụ đó vào cuối Event Loop queue, giúp "giải phóng" luồng chính ngay lập tức.

Vậy, khi nào nên "triệu hồi" setTimeout?

  • Khi em cần trì hoãn một hành động ĐƠN LẺ: Chỉ muốn chạy một lần sau X giây.
  • Khi muốn tạo các hiệu ứng UI/UX: Như loading, thông báo tự ẩn, animation có độ trễ.
  • Khi cần "lọc nhiễu" từ các sự kiện liên tục: Debounce các input, resize window, scroll events.
  • Khi cần "nhường đường" cho các tác vụ khác: setTimeout(..., 0) để đẩy tác vụ xuống cuối Event Loop cycle hiện tại.

Và khi nào thì nên "né" nó?

  • Khi cần độ chính xác thời gian cực cao: Đừng dùng nó để điều khiển tên lửa hay tính toán quỹ đạo vệ tinh nhé. Dùng các module chuyên biệt hoặc cron jobs cho các tác vụ hẹn giờ chính xác.
  • Khi cần lặp đi lặp lại một tác vụ: Dùng setInterval() hoặc các thư viện scheduler chuyên dụng để quản lý các tác vụ định kỳ tốt hơn.
  • Khi xử lý các tác vụ nặng, tốn thời gian: setTimeout vẫn chạy trên luồng chính. Nếu callback của em quá nặng, nó vẫn sẽ chặn Event Loop. Lúc đó, hãy nghĩ đến Worker Threads (trong Node.js) để xử lý ở luồng riêng.

Đó, setTimeout() tưởng chừng đơn giản nhưng lại là một công cụ cực kỳ mạnh mẽ nếu em biết cách dùng nó đúng lúc, đúng chỗ. Hãy thực hành thật nhiều để biến nó thành siêu năng lực của riêng mình nhé! Hẹn gặp lại trong bài học tiếp theo!

Thuộc Series: Nodejs

Bài giảng này được tự động xuất bản ngẫu nhiên từ thư viện kiến thức. Đừng quên đón xem các Từ khoá Hướng Dẫn tiếp theo nhé!

#tech #cyberpunk #laravel
Chỉnh sửa bài viết

Bình luận (0)

Vui lòng Đăng Nhập để Bình luận

Hỗ trợ Markdown cơ bản
Nguyễn Văn A
1 ngày trước

Tính năng này đỉnh quá ad ơi, chờ mãi mới thấy một blog Tiếng Việt có UI/UX xịn như vầy!