
Chào các Gen Z tương lai của ngành lập trình! Hôm nay, anh Creyt sẽ cùng các em 'mổ xẻ' một 'siêu năng lực' mà bất kỳ developer Node.js nào cũng phải biết: đó là timers.setInterval(). Nghe tên cứ như 'thần chú' trong Harry Potter vậy, nhưng thực ra nó là một công cụ cực kỳ quyền năng để code của chúng ta không chỉ 'chạy' mà còn biết 'tự động lặp lại' nữa đấy!
setInterval() là gì và để làm gì? (aka 'Auto-pilot' cho Code)
Trong thế giới code, không phải lúc nào chúng ta cũng muốn một tác vụ chạy một lần rồi thôi. Đôi khi, chúng ta cần một cái gì đó lặp đi lặp lại, như việc em check TikTok mỗi 5 phút, hay server game cần cập nhật vị trí người chơi mỗi giây. Đó chính là lúc setInterval() nhảy vào như một 'người hùng'!
Giải thích Gen Z-style: setInterval() giống như việc em cài đặt một cái báo thức 'tự động lặp lại' hàng ngày, hàng giờ vậy. Em bảo nó: "Này, cứ sau mỗi X mili giây, mày làm cái việc Y này cho tao nhé!" Và nó sẽ răm rắp nghe lời, lặp đi lặp lại mãi mãi... cho đến khi em bảo nó dừng lại.
Về bản chất hàn lâm hơn: setInterval() là một hàm toàn cục trong Node.js (và cả trình duyệt) cho phép chúng ta thực thi một hàm (callback function) lặp đi lặp lại sau một khoảng thời gian cố định. Nó trả về một ID (timer ID) mà chúng ta có thể dùng để 'hủy' việc lặp lại đó sau này bằng clearInterval().
Cú pháp cơ bản của nó trông như thế này:
setInterval(callback, delay, [...args]);
callback: Hàm mà bạn muốn thực thi lặp đi lặp lại.delay: Khoảng thời gian (tính bằng mili giây) giữa mỗi lần thực thicallback. Nó giống như độ trễ giữa các lần chuông báo thức reo vậy....args: (Tùy chọn) Các đối số bạn muốn truyền vào hàmcallbackmỗi khi nó được gọi.
Code Ví Dụ Minh Họa Rõ Ràng (Tập đếm và Dừng lại đúng lúc)
Để các em dễ hình dung, anh Creyt có hai ví dụ siêu dễ hiểu đây:
Ví dụ 1: Đồng hồ đếm ngược đơn giản
Giả sử chúng ta muốn một cái đồng hồ đếm ngược từ 5 về 0, và khi về 0 thì dừng lại.
let count = 5;
console.log('Bắt đầu đếm ngược...');
const countdownInterval = setInterval(() => {
console.log(`Còn lại: ${count} giây!`);
count--;
if (count < 0) {
clearInterval(countdownInterval); // Dừng lại khi đếm hết
console.log('Hết giờ! Chúc mừng!');
}
}, 1000); // Lặp lại mỗi 1000 mili giây (1 giây)
console.log('Đang chờ đếm ngược...');
Phân tích:
- Chúng ta khởi tạo
count = 5. setIntervalđược gọi với một hàm mũi tên (arrow function) làmcallbackvà1000ms làmdelay.- Mỗi giây, hàm
callbacksẽ in ra giá trịcountvà giảmcountđi 1. - Quan trọng nhất: Khi
countxuống dưới 0, chúng ta gọiclearInterval(countdownInterval)để 'giải phóng' cái báo thức này. Nếu không, nó cứ tiếp tục chạy mãi, cố gắng đếm -1, -2,... và làm hao tốn tài nguyên vô ích.

Mẹo (Best Practices) để ghi nhớ hoặc dùng thực tế
-
Luôn có
clearInterval(): Đây là quy tắc vàng!setInterval()giống như em 'bật' một công tắc, nếu không 'tắt' nó đi bằngclearInterval()thì nó sẽ chạy mãi, gây rò rỉ bộ nhớ (memory leak) hoặc thực hiện những tác vụ không mong muốn. Hãy nhớ,clearInterval()cần cái ID màsetInterval()trả về để biết phải tắt cái nào.
-
Cẩn thận với 'drift' thời gian:
setInterval()không đảm bảo rằng hàmcallbacksẽ được thực thi chính xác sau mỗidelaymili giây. Nó chỉ đảm bảo rằng hàmcallbacksẽ được đưa vào hàng đợi (event queue) saudelaymili giây. Nếu hàmcallbackmất nhiều thời gian để chạy, hoặc Event Loop đang bận, thì lần thực thi tiếp theo có thể bị trễ. Đây gọi là 'drift' thời gian. -
Không chặn Event Loop: Hàm
callbackcủa bạn nên gọn nhẹ và chạy nhanh. Nếu nó làm những tác vụ nặng (tính toán phức tạp, I/O blocking), nó sẽ 'chặn' Event Loop, làm chậm toàn bộ ứng dụng của bạn. Nếu cần tác vụ nặng, hãy cân nhắc dùngworker_threadshoặc chia nhỏ tác vụ. -
Khi cần độ chính xác cao, dùng
setTimeoutđệ quy: Đối với các tác vụ yêu cầu độ chính xác thời gian cao hơn và muốn tránh 'drift', một pattern phổ biến là dùngsetTimeoutgọi đệ quy chính nó. Điều này đảm bảo mỗi lần thực thi sẽ tính toándelaytừ thời điểm kết thúc của lần thực thi trước, tránh chồng chéo.function preciseInterval() { // Làm gì đó ở đây... console.log('Thực thi tác vụ chính xác hơn lúc: ', new Date().toLocaleTimeString()); // Sau khi tác vụ hoàn thành, lên lịch cho lần tiếp theo setTimeout(preciseInterval, 1000); } // preciseInterval(); // Bắt đầu lần đầu
Ứng dụng thực tế: Ai đã dùng và dùng thế nào?
setInterval() được dùng rộng rãi trong rất nhiều ứng dụng mà các em vẫn hay dùng hằng ngày đó:
- Real-time Dashboards/Chat Apps: Các ứng dụng hiển thị dữ liệu thời gian thực như giá cổ phiếu, tỷ số thể thao, hoặc tin nhắn chat mới thường dùng
setInterval()(hoặc WebSocket, nhưngsetIntervalcó thể dùng để polling dữ liệu cũ) để định kỳ gửi yêu cầu đến server để lấy dữ liệu mới nhất và cập nhật giao diện. - Game Servers (cơ bản): Trong các game online, server thường cần cập nhật trạng thái game (vị trí người chơi, trạng thái vật phẩm, AI của NPC) theo một nhịp độ nhất định.
setInterval()có thể được dùng để chạy 'game loop' cơ bản trên server. - Scheduled Tasks: Các hệ thống cần thực hiện các tác vụ định kỳ như dọn dẹp database, gửi email nhắc nhở, kiểm tra tính toàn vẹn dữ liệu, v.v. (Mặc dù trong Node.js, các thư viện như
node-cronthường được ưa chuộng hơn cho các tác vụ phức tạp). - Animations (trong trình duyệt): Dù
requestAnimationFramethường tốt hơn cho animation mượt mà,setInterval()vẫn có thể được dùng cho các animation đơn giản hoặc các hiệu ứng lặp đi lặp lại.
Thử nghiệm đã từng và Hướng dẫn nên dùng cho case nào?
Anh Creyt đã từng chứng kiến nhiều bạn trẻ 'say mê' setInterval() đến mức dùng nó mọi lúc mọi nơi, và rồi gặp phải đủ thứ vấn đề. Vậy nên, đây là lời khuyên từ 'lão làng' Creyt:
Khi nào nên dùng setInterval()?
- Polling dữ liệu: Khi bạn cần định kỳ kiểm tra một nguồn dữ liệu (API, database) để xem có sự thay đổi nào không, và độ trễ vài trăm mili giây không phải là vấn đề lớn.
- Cập nhật UI/UX đơn giản: Ví dụ, một đồng hồ đếm ngược, một thanh tiến trình cập nhật mỗi giây, hoặc một banner quảng cáo tự động chuyển đổi.
- Tác vụ nền không quá quan trọng về thời gian: Các tác vụ mà việc thực thi hơi trễ một chút cũng không ảnh hưởng nghiêm trọng đến logic của ứng dụng.
Khi nào nên CÂN NHẮC hoặc KHÔNG nên dùng setInterval()?
- Tác vụ nặng, tốn thời gian: Nếu hàm
callbackcủa bạn mất nhiều thời gian để hoàn thành hơn cảdelaymà bạn đặt ra, bạn sẽ gặp tình trạng các lần thực thi chồng chéo lên nhau, gây quá tải hệ thống và 'lag'. Hãy tưởng tượng em đặt báo thức 5 phút nhưng việc 'tắt' báo thức và chuẩn bị cho lần tiếp theo mất 6 phút vậy. Hỗn loạn ngay! - Yêu cầu độ chính xác thời gian cao: Như đã nói ở phần 'drift',
setInterval()không phải là lựa chọn tối ưu cho các hệ thống đòi hỏi độ chính xác tuyệt đối về thời gian. Lúc này,setTimeoutđệ quy hoặc các thư viện chuyên dụng sẽ là bạn tốt hơn. - Khi tác vụ cần phải hoàn thành trước khi bắt đầu lần tiếp theo: Nếu mỗi lần chạy của
callbackphụ thuộc vào việc lần trước đã kết thúc, thìsetTimeoutđệ quy là lựa chọn an toàn hơn nhiều.
Lời kết của anh Creyt: setInterval() là một công cụ mạnh mẽ, giúp code của chúng ta trở nên 'sống động' và tự động hơn rất nhiều. Nhưng như mọi công cụ quyền năng khác, nó cần được sử dụng một cách thông minh và có trách nhiệm. Hãy luôn nhớ 'thuần hóa' nó bằng clearInterval() và đừng để nó 'chạy hoang' làm hỏng Event Loop của các em nhé! Thực hành nhiều vào, và các em sẽ sớm làm chủ được 'thần chú' này thôi!
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é!