JavaScript là ngôn ngữ của web. Và nó đã không còn giống như vậy kể từ khi ES5 được phát hành. Ngày càng có nhiều ý tưởng và tính năng được chuyển từ các ngôn ngữ khác nhau và được tích hợp trong JavaScript.
Một trong những tính năng đó là Promise, đây có lẽ là tính năng được sử dụng rộng rãi nhất trong JavaScript sau khi ES5 được phát hành.
Nhưng một trong những điều mà JavaScript bỏ qua là cách “tạm dừng” thực thi trong một thời gian và tiếp tục lại sau. Trong bài đăng này, tôi sẽ thảo luận về cách bạn có thể đạt được điều đó và ý nghĩa thực sự của việc “tạm dừng” hoặc “ngủ” trong JavaScript.
Spoiler: JavaScript không bao giờ thực sự “tạm dừng”.
TL;DR
Đây là mã copy-pasta thực hiện công việc:
/**
*
* @param duration Enter duration in seconds
*/
function sleep(duration) {
return new Promise(resolve => {
setTimeout(() => {
resolve()
}, duration * 1000)
})
}
Nhưng điều gì đang thực sự xảy ra ở đây?
setTimeout và lời hứa giả
Hãy xem một ví dụ nhanh bằng cách sử dụng đoạn mã trên (chúng ta sẽ thảo luận về những gì đang xảy ra trong đó sau):
async function performBatchActions() {
// perform an API call
await performAPIRequest()
// sleep for 5 seconds
await sleep(5)
// perform an API call again
await performAPIRequest()
}
Chức năng này performBatchActions
khi được gọi, chỉ cần thực hiện lệnh performAPIRequest
chức năng, chờ đợi khoảng 5 giây, và sau đó gọi lại chức năng tương tự. Lưu ý cách tôi đã viết khoảng 5 giâyvà không phải 5 giây.
Một lưu ý mạnh mẽ để đưa ra đó: đoạn mã trên không đảm bảo một giấc ngủ hoàn hảo. Điều đó có nghĩa là nếu bạn chỉ định thời lượng là 1 giây, JavaScript không đảm bảo rằng nó sẽ bắt đầu chạy mã sau khi ngủ chính xác sau 1 giây.
Tại sao không? bạn có thể yêu cầu. Thật không may, đó là do bộ hẹn giờ hoạt động trong JavaScript và nói chung là các vòng lặp sự kiện. Tuy nhiên, JavaScript hoàn toàn đảm bảo rằng đoạn mã sau khi ngủ sẽ không bao giờ thực thi trước thời gian quy định.
Vì vậy, chúng tôi không thực sự có một tình huống không xác định đầy đủ, chỉ là một phần. Và trong hầu hết các trường hợp, nó chỉ nằm trong biên độ vài mili giây.
JavaScript là luồng đơn
Một luồng duy nhất có nghĩa là một quy trình JavaScript thực sự không thể đi chệch hướng. Nó phải làm tất cả mọi thứ – từ trình xử lý sự kiện, đến các cuộc gọi lại HTTP, trên cùng một luồng chính. Và khi một thứ đang thực hiện, một thứ khác không thể thực hiện được.
Hãy xem xét một trang web trong đó bạn có nhiều nút và bạn chạy mã ở trên để mô phỏng chế độ ngủ trong 10 giây. Bạn mong đợi điều gì sẽ xảy ra?
Không có gì đâu. Trang web của bạn sẽ hoạt động tốt, các nút của bạn sẽ phản hồi nhanh và sau khi hoàn tất 10 giây ngủ, mã bên cạnh nó sẽ thực thi. Vì vậy, rõ ràng là JavaScript không thực sự chặn toàn bộ chuỗi chính bởi vì nếu nó làm như vậy, trang web của bạn sẽ bị đóng băng và các nút sẽ không thể nhấp được.
Vậy làm thế nào mà JavaScript thực sự tạm dừng một luồng mà không thực sự tạm dừng nó?
Gặp vòng lặp sự kiện
Không giống như các ngôn ngữ khác, JavaScript không chỉ tiếp tục thực thi mã theo kiểu tuyến tính từ trên xuống dưới. Nó là một ngôn ngữ hướng sự kiện không đồng bộ với vô số phép thuật ở dạng vòng lặp sự kiện.
Vòng lặp sự kiện phân tách mã của bạn thành các sự kiện nhất định và đồng bộ – như bộ hẹn giờ và yêu cầu HTTP. Nói một cách chính xác, có hai hàng đợi – hàng đợi tác vụ và hàng đợi vi tác vụ.
Bất cứ khi nào bạn chạy JS và có một thứ không đồng bộ (như sự kiện click chuột hoặc lời hứa), JavaScript sẽ ném nó vào hàng đợi tác vụ (hoặc hàng đợi vi tác vụ) và tiếp tục thực thi. Khi nó hoàn thành một “lần đánh dấu”, nó sẽ kiểm tra xem hàng đợi nhiệm vụ và hàng đợi vi nhiệm vụ có một số công việc cho nó hay không. Nếu có, thì nó sẽ thực hiện gọi lại/thực hiện một hành động.
Tôi thực sự khuyên bất kỳ ai quan tâm đến hoạt động chi tiết của các vòng lặp sự kiện nên xem video này:
Phần kết luận
Bạn đến đây để xem hướng dẫn về chế độ ngủ đơn giản trong JavaScript và cuối cùng lại tìm hiểu về một trong những điều cốt lõi trong JavaScript – vòng lặp sự kiện! Tuyệt vời phải không?
Chà, nếu bạn thích bài viết này, hãy xem codedamn – một nền tảng mà tôi đã và đang xây dựng cho các nhà phát triển và người học như bạn. Ngoài ra, hãy kết nối trên phương tiện truyền thông xã hội – Twitter và Instagram. Hẹn sớm gặp lại!
Hòa bình