Code gốc sẽ tương đương với code này
function "queryDB" giữ nguyên
app.get('/', (req, res) => {
queryDB().then(_ => console.log('Hello World!'))
//console.log('This will always run, no delay');
})
nghĩa là nó queryDB xong thì mới log ra
==========================================
Quay lại cơ bản
- Code async/await sẽ đc viết lại thành như trên.
- QueryDB là async
- console.log là sync.
- Do không dùng cluster/child nên Node đang chạy trên 1 luồng duy nhất.
- Khi lần 1, user A vào url, queryDB đc chạy, do nó là async -> xếp vào 1 chỗ, xử lý sau -> chạy xuống xử lý tiếp.
- Như đã thấy trong code đc viết lại, không có lệnh nào ở dưới queryDB cả.
- Cùng lúc đó, user B lại vào url, lại chạy queryDB -> xếp vào 1 chỗ, và xếp sau sau cái queryDB mà user A đã chạy ở trên
- Hàng đợi hay queue sẽ thế này
[queryDB (userA), queryDB (userB)]
- Khi không còn code dạng sync nữa thì engine bắt đầu chạy code async ở trong queue. (thực ra event-loop nó phức tạp hơn nhưng tạm hiểu vậy đi - sync luôn chạy trước async)
Nên user B phải đợi là dễ hiểu.
Để đạt được yêu cầu thì chỉ cần vứt cái console.log ra ngoài là đc (ví dụ như dòng comment ở code rewrite ở trên)
Hoặc đừng await nữa, vì await bản chất sẽ đc chuyển thành như code rewrite (tức là wrap toàn bộ code sau await vào trong hàm chính)
code đã xóa await (k dùng await nên bỏ async luôn)
app.get('/', (req, res) => {
queryDB();
res.send('Hello World!')
})
=====================================
Như vậy, nếu 1 task chạy quá lâu thì sẽ ảnh hưởng tới người dùng. Vì thế người ta mới nghĩ ra trò đa luồng, mỗi 1 user 1 luồng, không ai đợi ai hết.
Cluster/Child process trong node cũng có cơ chế tương tự như đa luồng.
=====================================
Không biết sao câu trả lời SO kia lại đc vote, rõ ràng không có chuyện browser chỉ giới hạn 1 request 1 lần, nghe đã vô lý, chưa cần test.