Chúng cho phép duyệt một nguồn dữ liệu bất đồng bộ như một vòng lặp bình thường, mà không phải nạp toàn bộ vào bộ nhớ trước.
Hợp cho phân trang, đọc stream, tail log.
async function* fetchPages(url, signal) {
let cursor = null
do {
const res = await fetch(`${url}?cursor=${cursor ?? ''}`, { signal })
const page = await res.json()
yield* page.items // trả từng item ra ngoài
cursor = page.nextCursor
} while (cursor)
}
for await (const order of fetchPages('/api/orders', signal)) {
process(order)
if (shouldStop) break // break gọi generator.return() -> chạy finally để dọn dẹp
}Ưu điểm so với vòng while tự viết: logic phân trang được đóng gói, phía tiêu thụ chỉ thấy một luồng item; lazy nên chỉ gọi trang kế khi thật sự cần; break/throw sẽ kích hoạt finally bên trong generator để đóng tài nguyên.
Giới hạn cần nêu khi phỏng vấn:
- for await...of luôn tuần tự — không tự song song hoá. Cần song song thì gom item rồi Promise.all từng lô, hoặc dùng worker pool.
- Lỗi trong generator sẽ ném ra tại vòng lặp, nên try/catch bao quanh for await là đủ.
- for await...of cũng chạy được trên mảng Promise thường (ReadableStream trong trình duyệt hiện đại cũng async iterable).