Callback hell (pyramid of doom) là chuỗi callback lồng nhau nhiều tầng, error handling lặp lại ở từng tầng và logic khó theo dõi:
js
fs.readFile('a.txt', (err, data) => {
if (err) throw err
db.query(data, (err, rows) => {
if (err) throw err
sendEmail(rows[0], (err) => {
if (err) throw err
console.log('done')
})
})
})Promise chaining làm phẳng bớt nhưng vẫn vướng khi cần truyền nhiều giá trị qua các bước:
js
readFile('a.txt')
.then((data) => db.query(data))
.then((rows) => sendEmail(rows[0]))
.catch((err) => console.error(err))async/await đọc như code đồng bộ, try/catch dùng như bình thường:
js
try {
const data = await readFile('a.txt')
const rows = await db.query(data)
await sendEmail(rows[0])
} catch (err) {
console.error(err)
}Khác biệt lớn nhất nằm ở đường đi của lỗi: callback phải tự kiểm tra err ở mọi tầng, bỏ sót một chỗ là lỗi bị nuốt mất mà không ai hay; còn Promise/async thì lỗi tự bubble lên .catch/try-catch.
Lưu ý: await trong vòng lặp for...of chạy tuần tự — cần song song thì dùng Promise.all(items.map(item => process(item))).