⚙️ XỬ LÝ BẤT ĐỒNG BỘ – CẤP ĐỘ THỰC CHIẾN
Chương 1: Hiểu Sâu JavaScript Runtime & Bất Đồng Bộ
1.1. JavaScript Runtime Environment
JavaScript ban đầu được thiết kế để chạy trong trình duyệt, nhưng với sự ra đời của Node.js, ngôn ngữ này đã có thể vận hành ở backend. Dù chạy trong browser hay server, JavaScript luôn hoạt động trong một "runtime environment" với nhiều thành phần quan trọng:
1.1.1. Call Stack
Là ngăn xếp (stack) để theo dõi hàm nào đang được thực thi. Mỗi khi một hàm được gọi, nó được đẩy vào stack; khi kết thúc, nó bị lấy ra.
1.1.2. Heap
Là vùng nhớ cho Object và tham chiếu, được sử dụng cho các giá trị không phải primitive.
1.1.3. Web APIs / C++ Bindings
Chỉ có trong browser/Node. Browser cung cấp Web API (như setTimeout
, DOM
, fetch
), còn Node.js cung cấp các binding như fs
, http
, net
.
1.1.4. Callback Queue / Task Queue
Queue chờ các hàm async như setTimeout
, setInterval
, I/O v.v. Macrotask Queue và Microtask Queue là 2 loại chính.
1.1.5. Event Loop
Trái tim của JavaScript: luân phiên đẩy task từ queue vào call stack khi stack rỗng.
1.2. Event Loop trong thực tiễn
console.log("A");
setTimeout(() => console.log("B"), 0);
Promise.resolve().then(() => console.log("C"));
console.log("D");
Kết Quả:
A
D
C
B
Giải thích:
A
vàD
: chạy ngay trong call stackPromise.then
: đưa vào Microtask Queue, chạy sau khi call stack rỗngsetTimeout
: vào Macrotask Queue, chạy sau microtask
1.3. Callback
Định nghĩa:
Là một hàm được truyền làm đối số và được gọi sau khi hoàn thành tác vụ.
function fetchData(callback) {
setTimeout(() => callback("Done"), 1000);
}
Nhược điểm:
Callback hell
Khó debug
Tổ chức logic phức tạp
1.4. Promise
Định nghĩa:
Là một object đại diện cho kết quả bất đồng bộ tương lai
const promise = new Promise((resolve, reject) => {
if (success) resolve(data);
else reject(error);
});
Trạng thái:
Pending
Fulfilled
Rejected
1.5. Promise Chaining
fetchUser()
.then((user) => fetchProfile(user.id))
.then((profile) => console.log(profile))
.catch(console.error);
Lời ích:
Code dễ đọc
Tách rời xử lý logic và lỗi
1.6. Async / Await
async function loadProfile() {
try {
const user = await fetchUser();
const profile = await fetchProfile(user.id);
console.log(profile);
} catch (err) {
console.error(err);
}
}
Lời ích:
Code đọc tuỳ như đồng bộ
Dễ debug
1.7. Promise.all, allSettled, race
const [res1, res2] = await Promise.all([api1(), api2()]);
Promise.all
: chờ tất cả resolve, fail 1 là reject toàn bộPromise.allSettled
: resolve tất cả, báo trạng tháiPromise.race
: resolve/reject đầu tiên
1.8. Debounce & Throttle
Debounce:
Chỉ chạy sau một khoảng delay nếu ngưng gọi
function debounce(fn, delay) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
Throttle:
Giới hạn tần suất gọi trong khoảng thời gian
function throttle(fn, limit) {
let lastCall = 0;
return (...args) => {
const now = Date.now();
if (now - lastCall >= limit) {
lastCall = now;
fn.apply(this, args);
}
};
}
1.9. Tổng Kết
Runtime
Nền tảng vận hành cho JS
Event Loop
Cơ chế điều phối bất đồng bộ
Callback/Promise
Cách xử lý async logic
Async/Await
Code async dễ hiểu, gắn với Promise
Debounce/Throttle
Tối ưu hiệu suất trong UI
Promise.all
Chờ nhiều promise song song, rất quan trọng trong API calls
Trong những hệ thống lớn, việc nắm vững những kiến thức trên giúp senior developer viết code bền vững, scale được và xử lý tình huống async phức tạp một cách chính xác.
Last updated