11/08/2018, 20:15

[nodeJs] setTimeout, setImmediate và process.nextTick

Ba cái phương thức này có vẻ giống giống nhau. Bài này lí giải sự khác nhau của 3 đứa chúng nó. An event loop refresh Giả sử rằng bạn đã hiểu về Javascript event loop. Giả sử chưa, thì ở đây tôi tóm tắt lại qua một hình ảnh. Hoặc bạn có thể ngồi đọc ở đây Stack là nơi lưu giữ các ...

Ba cái phương thức này có vẻ giống giống nhau. Bài này lí giải sự khác nhau của 3 đứa chúng nó.

An event loop refresh

Giả sử rằng bạn đã hiểu về Javascript event loop. Giả sử chưa, thì ở đây tôi tóm tắt lại qua một hình ảnh. Hoặc bạn có thể ngồi đọc ở đây

  • Stack là nơi lưu giữ các con trỏ hàm đang thực hiện,. Khi hàm bắt đầu chạy thì nhảy vào đây, hàm nào xong rồi thì cút. Do bản chất stack nên thằng nào vào sau sẽ cút trước.

  • Queue là hàng đợi sự kiện, mỗi thằng sự kiện mới sẽ chui vào đây, thằng nào vào trước lấy trước. Sự kiện có thể là I/O event, timeout event, interval event, v.v..

  • Event loop là 1 thằng chuyên đi nhặt các sự kiện trong hàng đợi để xử lý. Tuy nhiên nó chỉ nhặt khi và chỉ khi stack trống.

Timeout

Thằng này gà, lúc nào nó cũng bắt buộc phải đặt message của nó ở cuối hàng đợi. Ví dụ

setTimeout(() => {
   //no op
}, 200)

Chạy đến vị trí 200ms nữa, nếu chưa có thằng nào đợi ở đấy mới được đứng, còn không thì cút xuống cuối hàng. Như vậy lúc nào nó cũng phải đợi nhiều hơn, cùng lắm là bằng 200ms.

Immediate

setImmediate(() => {

})

Thằng này là con của bố nó, cháu của ông nó, nên ưu tiên hơn thằng Ao, nó được đứng trước thằng Ao, và chỉ phải chờ các thằng sự kiện vào/ra (I/O).

Như vậy thằng setImmediate được run trước thằng setTimeout, dù setTimeout 0ms.

process.nextTick

process.nextTick(() => {

})

Thằng này thân thế nó cực khủng, không tiện nói ra đây. Chỉ biết nó không thèm đứng vào hàng đợi mà có cửa VIP. Khi nào stack trống, tức là hết tick, nó được thực hiện luôn. Thằng event loop chỉ biết đứng há hốc mồm ra xem mà không dám process event tiếp theo.

Tuy nhiên nó vẫn không thể break được stack đang thực hiện. Công bằng làm sao.

CHÚ Ý: 2 thằng sau chỉ có trong nodejs, không có trong Javascript nói chung. Mà tôi thấy cũng chẳng mấy khi dùng. Bài này viết chỉ để phản đối một ý trong comment của anh Vũ Nhật Minh (@VuNhatMinh): "timeout 0 không "đợi" thêm chút thời gian nào, " ở đây

0