Trong quá trình phát triển ứng dụng WeChat Mini Program, việc xử lý các tác vụ bất đồng bộ theo thời gian là rất phổ biến. Hai công cụ chính để thực hiện điều này trong JavaScript là setTimeout và setInterval. Tuy nhiên, việc sử dụng chúng trong môi trường Mini Program đòi hỏi sự cẩn trọng về quản lý vòng đời để tránh rò rỉ bộ nhớ hoặc lỗi logic.
1. Cơ chế hoạt động của setTimeout
setTimeout được sử dụng khi bạn muốn thực thi một đoạn mã hoặc một hàm duy nhất sau một khoảng thời gian chờ đợi nhất định (tính bằng mili giây).
// Cách 1: Sử dụng hàm ẩn danh
setTimeout(function() {
console.log("Hành động thực hiện sau 1 giây");
}, 1000);
// Cách 2: Sử dụng Arrow Function (Khuyến khích trong Mini Program)
setTimeout(() => {
console.log("Xử lý dữ liệu sau 2 giây");
}, 2000);
// Cách 3: Gọi hàm có tham số
function taskLogger(msg, priority) {
console.log(`Thông báo: ${msg}, Mức độ: ${priority}`);
}
const timerId = setTimeout(taskLogger, 1500, "Hệ thống đã sẵn sàng", "Cao");
Hủy bỏ setTimeout:
Để ngăn chặn một tác vụ chưa kịp thực thi, chúng ta sử dụng hàm clearTimeout với ID được trả về từ setTimeout.
const delayAction = setTimeout(() => {
console.log("Lệnh này sẽ không được in ra");
}, 5000);
// Hủy bỏ ngay lập tức
clearTimeout(delayAction);
2. Cơ chế hoạt động của setInterval
Khác với setTimeout, setInterval sẽ lặp đi lặp lại việc thực thi một hàm sau mỗi khoảng thời gian cố định cho đến khi bị dừng lại một cách chủ động.
// Cập nhật trạng thái mỗi 3 giây
const pollingId = setInterval(() => {
console.log("Đang kiểm tra dữ liệu mới từ máy chủ...");
}, 3000);
// Dừng việc lặp lại
function stopSync() {
clearInterval(pollingId);
console.log("Đã dừng đồng bộ dữ liệu.");
}
3. Áp dụng trong vòng đời của WeChat Mini Program
Một lỗi phổ biến mà các nhà phát triển thường gặp phải là quên dọn dẹp các bộ định thời khi người dùng chuyển trang hoặc thoát ứng dụng. Trong WeChat Mini Program, nếu bạn khởi tạo một setInterval trong onLoad nhưng không xóa nó trong onUnload, hàm đó sẽ tiếp tục chạy ngầm, gây tiêu tốn tài nguyên và tạo ra các instance chồng chéo khi người dùng quay lại trang.
Page({
data: {
counter: 0,
timerRef: null
},
onLoad: function() {
// Khởi tạo bộ đếm
this.startCounter();
},
startCounter: function() {
const id = setInterval(() => {
this.setData({
counter: this.data.counter + 1
});
console.log("Giá trị hiện tại:", this.data.counter);
}, 1000);
// Lưu tham chiếu vào data hoặc thuộc tính của Page
this.setData({ timerRef: id });
},
clearAllTimers: function() {
if (this.data.timerRef) {
clearInterval(this.data.timerRef);
this.setData({ timerRef: null });
}
},
/**
* Khi người dùng ẩn ứng dụng hoặc chuyển sang tab khác
*/
onHide: function() {
this.clearAllTimers();
},
/**
* Khi trang bị đóng hoàn toàn
*/
onUnload: function() {
this.clearAllTimers();
}
});
Lưu ý quan trọng:
- Thời gian delay tối thiểu trong thực tế có thể không chính xác tuyệt đối 1ms do hàng đợi sự kiện (Event Loop) của hệ thống.
- Đối với các tác vụ đếm ngược phức tạp hoặc cần độ chính xác cao (như đồng hồ bấm giờ), nên so sánh
Date.now()thay vì chỉ dựa vào số lần chạy củasetInterval. - Luôn đảm bảo biến lưu trữ ID định thời được khởi tạo giá trị
nullđể dễ dàng kiểm tra trạng thái trước khiclear.