JavaScript là một ngôn ngữ đơn luồng, chỉ có một tác vụ được thực hiện tại một thời điểm. Nếu tác vụ đó tốn nhiều thời gian, các tác vụ khác sẽ phải chờ để được thực thi. Điều này làm cho ứng dụng bị chặn lại và giao diện sẽ bị treo.
Sự xuất hiện của web API giúp cho các tác vụ có thể được thực thi song song với nhau dựa trên một cơ chế, được gọi là event loop.
Explanation
Các lời gọi hàm trong JavaScript được lưu trên call stack tương tự các ngôn ngữ lập trình khác (xem thêm Program Execution).
Giả sử ta có đoạn code sử dụng hàm setTimeout
sau.
Hàm greet
sẽ được thêm vào call stack, được thực thi, rồi bị xóa khỏi call stack. Hàm respond
đến sau cũng được thêm vào call stack.
Tuy nhiên, callback của hàm setTimeout
sẽ được Web API xử lý thay vì được thêm vào call stack.
Lúc này, do không còn gì để thực thi, respond
sẽ bị xóa khỏi call stack.
Sau khi hết thời gian delay (1000 ms), web API sẽ đẩy callback trong setTimeout
vào một hàng đợi.
Nếu call stack trống, phần tử đầu tiên của hàng đợi sẽ được đẩy vào call stack và được thực thi.
Example
Xét đoạn code dưới đây:
const foo = () => console.log("First")
const bar = () => setTimeout(() => console.log("Second"), 500)
const baz = () => console.log("Third")
bar()
foo()
baz()
Hàm bar
sẽ được đẩy vào call stack do được gọi thực thi đầu tiên. Callback truyền vào sẽ được chuyển qua cho Web API xử lý.
Do Web API hoạt động song song với luồng chương trình, nó sẽ không chặn các tác vụ đến sau, mà cụ thể ở đây là hàm foo
và hàm baz
.
Hàm foo
và hàm baz
sẽ được thêm vào callstack trong lúc Web API xử lý tác vụ.
Nếu Web API hoàn tất tác vụ, callback được trả về phải chờ ở trong hàng đợi cho đến khi call stack hoàn toàn trống thì mới được thực thi.
Sau khi hàm baz
thực thi xong tác vụ, console sẽ có kết quả là:
First
Third
Thời điểm hàm baz
hoàn thành cũng là lúc mà call stack hoàn toàn trống, callback ở trong hàng đợi lúc này sẽ được đẩy vào call stack để được thực thi.
Kết quả cuối cùng trong console là:
First
Third
Second
Related
table tags as Tags, file.cday as Created
from [[Event Loop]]
sort file.ctime asc