Callback là hàm truyền vào một hàm khác để được gọi lại sau.
javascript
// callback đồng bộ — chạy ngay trong lượt hiện tại
;[1, 2, 3].map((n) => n * 2)
// callback bất đồng bộ — chạy ở lượt sau
setTimeout(() => console.log('xong'), 1000)
input.addEventListener('click', (e) => handle(e))JavaScript chạy một luồng. Nếu phải chờ mạng hay đĩa theo kiểu chặn, cả giao diện đứng im. Callback cho phép đăng ký "làm việc này khi có kết quả" rồi trả luồng lại cho trình duyệt.
Quy ước Node.js — error-first callback, vẫn gặp nhiều trong thư viện cũ:
javascript
fs.readFile('a.txt', (err, data) => {
if (err) return handleError(err) // lỗi luôn là tham số ĐẦU
console.log(data)
})Hai vấn đề khiến Promise ra đời:
1. Lồng nhiều tầng khi các bước phụ thuộc nhau (callback hell).
2. Không bắt lỗi bằng try/catch được, vì callback chạy ở lượt khác của event loop:
javascript
try {
setTimeout(() => { throw new Error('bùm') }, 0)
} catch (e) {
// KHÔNG vào đây — lỗi ném ở lượt sau
}Chốt: callback không lỗi thời — map, addEventListener, Array.sort đều là callback.
Cái được thay là callback bất đồng bộ nhiều tầng, và thứ thay nó là Promise/async-await.