vòng lặp sự kiện trong nút js

Vong Lap Su Kien Trong Nut Js



Node.js là một khung Javascript mạnh mẽ cho phép người dùng chạy mã Javascript trên máy chủ bên ngoài trình duyệt. Đây là môi trường thời gian chạy theo sự kiện, không chặn để xây dựng các ứng dụng web có khả năng mở rộng đáng tin cậy. Vòng lặp sự kiện là một phần quan trọng của Node.js, cho phép bạn thực hiện các tác vụ mà không cần đợi tác vụ này hoàn thành trước khi bắt đầu tác vụ khác.

Mặc dù Javascript là ngôn ngữ đơn luồng nhưng Node.js có thể gán tác vụ cho hệ điều hành, cho phép nó xử lý nhiều tác vụ cùng một lúc. Một số tác vụ phải được hoàn thành cùng lúc vì các hoạt động trong hệ điều hành là đa luồng. Cuộc gọi lại liên quan đến từng thao tác sẽ được thêm vào hàng đợi sự kiện và được Node.js lên lịch để chạy khi hoàn thành tác vụ đã chỉ định.

Để viết mã Node.js hiệu quả và đáng tin cậy, người dùng phải có hiểu biết vững chắc về các vòng lặp sự kiện. Nó cũng có thể giúp khắc phục các vấn đề về hiệu suất một cách hiệu quả. Vòng lặp sự kiện trong Node.js giúp tiết kiệm bộ nhớ và cho phép bạn thực hiện nhiều việc cùng một lúc mà không cần phải đợi từng việc hoàn thành. Thuật ngữ “không đồng bộ” dùng để chỉ bất kỳ chức năng Javascript nào chạy ở chế độ nền mà không chặn các yêu cầu gửi đến.







Trước khi chuyển thẳng sang vòng lặp sự kiện, chúng ta hãy xem xét các khía cạnh khác nhau của ngôn ngữ lập trình Javascript.



Javascript là ngôn ngữ lập trình không đồng bộ

Chúng ta hãy xem xét các khái niệm về lập trình không đồng bộ. Javascript được sử dụng trong các ứng dụng web, di động và máy tính để bàn, nhưng cần lưu ý rằng Javascript là ngôn ngữ lập trình máy tính đồng bộ, đơn luồng.



Một ví dụ mã đơn giản được đưa ra để hiểu khái niệm này.





phương thức hàm1 ( ) {

bảng điều khiển. nhật ký ( 'Chức năng 1' )

}

phương thức hàm2 ( ) {

bảng điều khiển. nhật ký ( 'Chức năng 2' )

}

phương pháp 1 ( )

phương pháp2 ( )

Trong mã này, hai hàm đơn giản được tạo và phương thức1 được gọi trước nên nó sẽ ghi lại phương thức1 trước rồi chuyển sang phương thức tiếp theo.

đầu ra



Javascript là ngôn ngữ lập trình đồng bộ

Javascript là ngôn ngữ lập trình đồng bộ và thực thi từng dòng từng bước từ trên xuống dưới với mỗi lần chỉ thực hiện một dòng. Trong mã ví dụ ở trên, phương thức 1 được ghi lại trước tiên trong thiết bị đầu cuối và sau đó là phương thức2.

Javascript làm ngôn ngữ chặn

Là một ngôn ngữ đồng bộ javascript có chức năng chặn. Không quan trọng phải mất bao lâu để hoàn thành một quy trình đang diễn ra nhưng quy trình mới sẽ không được bắt đầu cho đến khi quy trình trước đó được hoàn thành. Trong ví dụ mã trên, giả sử có rất nhiều tập lệnh mã trong phương thức 1, bất kể mất bao nhiêu thời gian, dù mất 10 giây hay một phút, phương thức 2 sẽ không được thực thi cho đến khi tất cả mã trong phương thức 1 được thực thi.

Người dùng có thể đã gặp phải điều này khi duyệt web. Khi một ứng dụng web thực thi trong trình duyệt ở phía sau, một đoạn mã lớn đang được thực thi nên trình duyệt dường như bị đóng băng một thời gian trước khi trả lại quyền truy cập điều khiển cho người dùng. Hành vi này được gọi là chặn. Trình duyệt không thể xử lý thêm bất kỳ yêu cầu nào đến cho đến khi yêu cầu hiện tại được xử lý.

Javascript là ngôn ngữ đơn luồng

Để chạy một chương trình bằng javascript, chức năng luồng được sử dụng. Chủ đề chỉ có khả năng thực hiện một nhiệm vụ tại một thời điểm. Các ngôn ngữ lập trình khác hỗ trợ đa luồng và có thể chạy song song nhiều tác vụ, javascript chỉ chứa một luồng để thực thi bất kỳ tập lệnh mã nào.

Đang chờ trong Javascript

Rõ ràng từ tên trong phần này, chúng tôi phải đợi yêu cầu của mình được xử lý để tiếp tục. Việc chờ đợi có thể mất vài phút trong đó không có yêu cầu nào khác được giải quyết. Nếu đoạn mã tiếp tục mà không chờ đợi thì mã sẽ gặp lỗi. Một số chức năng sẽ được triển khai trong Javascript hoặc cụ thể hơn là Node.js để làm cho mã không đồng bộ.

Bây giờ chúng ta đã hiểu các khía cạnh khác nhau của Javascript, chúng ta hãy hiểu đồng bộ và không đồng bộ bằng một số ví dụ đơn giản.

Thực thi mã đồng bộ trong Javascript

Đồng bộ có nghĩa là mã được thực thi tuần tự hoặc đơn giản hơn là từng bước bắt đầu từ trên cùng và di chuyển xuống từng dòng.

Dưới đây là một ví dụ được đưa ra có thể giúp hiểu:

// ứng dụng.js

bảng điều khiển. nhật ký ( 'Một' )

bảng điều khiển. nhật ký ( 'Hai' )

bảng điều khiển. nhật ký ( 'Ba' )

Trong mã này, có ba câu lệnh console.log, mỗi câu lệnh in một cái gì đó. Đầu tiên, câu lệnh đầu tiên sẽ in “One” trong bảng điều khiển sẽ được gửi vào ngăn xếp cuộc gọi trong 1 ms (ước tính), sau đó nó được ghi vào thiết bị đầu cuối. Sau đó, câu lệnh thứ hai được đẩy vào ngăn xếp cuộc gọi và bây giờ thời gian là 2 mili giây với một câu lệnh được thêm vào từ câu lệnh trước đó, sau đó nó ghi “Hai” vào bảng điều khiển. Cuối cùng, câu lệnh cuối cùng được đẩy vào ngăn xếp cuộc gọi với thời gian là 3 mili giây và nó ghi “Ba” vào bảng điều khiển.

Đoạn mã trên có thể được thực thi bằng cách gọi lệnh sau:

ứng dụng nút. js

đầu ra

Chức năng được giải thích chi tiết ở trên và bằng cách xem xét nó, đầu ra sẽ được ghi vào bảng điều khiển trong chớp mắt:

Thực thi mã không đồng bộ trong Javascript

Bây giờ chúng ta hãy cấu trúc lại mã tương tự bằng cách giới thiệu các lệnh gọi lại và làm cho mã không đồng bộ. Đoạn mã trên có thể được cấu trúc lại thành:

// ứng dụng.js
hàm printOne ( gọi lại ) {
    setTimeout ( chức năng ( ) {
bảng điều khiển. nhật ký ( 'Một' ) ;
gọi lại ( ) ;
} , 1000 ) ;
}
chức năng inHai ( gọi lại ) {
    setTimeout ( chức năng ( ) {
bảng điều khiển. nhật ký ( 'Hai' ) ;
gọi lại ( ) ;
} , 2000 ) ;
}
chức năng inBa ( ) {
    setTimeout ( chức năng ( ) {
bảng điều khiển. nhật ký ( 'Ba' ) ;
} , 3000 ) ;
}
bảng điều khiển. nhật ký ( 'Bắt đầu chương trình' ) ;
inMột ( chức năng ( ) {
inHai ( chức năng ( ) {
inBa ( ) ;
} ) ;
} ) ;
bảng điều khiển. nhật ký ( 'Kết thúc chương trình' ) ;

Trong mã này ở trên:

  • Ba hàm được khai báo để in “Một”, “Hai” và “Ba”, mỗi hàm có một tham số gọi lại cho phép thực thi mã tuần tự.
  • Thời gian chờ được đặt bằng hàm setTimeout và có câu lệnh console.log để in sau một khoảng thời gian trễ cụ thể.
  • Hai thông báo được in “Bắt đầu Chương trình” và “Kết thúc Chương trình” cho biết sự bắt đầu và kết thúc của chương trình.
  • Chương trình bắt đầu bằng cách in “Bắt đầu chương trình”, sau đó hàm printOne được thực thi với độ trễ 1 giây, sau đó hàm printTwo được thực thi với độ trễ 2 giây và cuối cùng hàm printThree được thực thi với độ trễ 3 giây. trì hoãn.
  • Chương trình không chờ thực thi mã không đồng bộ bên trong các hàm setTimeouts ghi lại câu lệnh “Kết thúc chương trình” trước khi in Một, Hai và Ba.

đầu ra

Chạy đoạn mã trên bằng cách thực hiện lệnh này trong terminal:

ứng dụng nút. js

Bây giờ đầu ra trong thiết bị đầu cuối sẽ hiển thị không đồng bộ như sau:

Bây giờ chúng ta đã hiểu đầy đủ về việc thực thi đồng bộ và không đồng bộ, hãy chuyển sang củng cố khái niệm về vòng lặp sự kiện trong Node.js.

Node.js: Cơ chế vòng lặp sự kiện

Việc thực thi cả tác vụ đồng bộ và không đồng bộ đều được quản lý bởi vòng lặp sự kiện trong Node.js. Quá trình thực thi được thực hiện ngay khi dự án Node.js được khởi chạy và chuyển các tác vụ phức tạp sang hệ thống một cách suôn sẻ. Điều này đảm bảo rằng các tác vụ khác có thể chạy trơn tru trên luồng chính.

Giải thích trực quan về Vòng lặp sự kiện trong Node.js

Vòng lặp sự kiện là liên tục và bán vô hạn trong Node.js. Vòng lặp sự kiện được gọi khi bắt đầu tập lệnh mã Node.js và nó chịu trách nhiệm thực hiện các lệnh gọi API không đồng bộ và gọi các tiến trình.Tick(), đồng thời lên lịch hẹn giờ sau đó tiếp tục thực hiện vòng lặp sự kiện.

Trong Node.js, năm loại hàng đợi chính xử lý lệnh gọi lại:

  • “Hàng đợi hẹn giờ” thường được gọi là min-heap chịu trách nhiệm xử lý các lệnh gọi lại liên quan đến “setTimeout” và “setInterval”.
  • Lệnh gọi lại cho các hoạt động không đồng bộ như trong mô-đun “fs” và “http” được xử lý bởi “Hàng đợi I/O”.
  • “Hàng đợi kiểm tra” chứa các lệnh gọi lại cho chức năng “setImmediate” dành riêng cho Node.
  • “Hàng đợi đóng” quản lý các cuộc gọi lại được liên kết với bất kỳ sự kiện kết thúc nào của tác vụ không đồng bộ.
  • Cuối cùng, có hai hàng đợi khác nhau trong hàng đợi “Tác vụ vi mô”:
    • Hàng đợi “nextTick” chứa các lệnh gọi lại được liên kết với hàm “process.nextTick”.
    • Hàng đợi “Promise” kiểm soát các lệnh gọi lại liên quan đến Promise gốc.

Chức năng Vòng lặp sự kiện trong Node.js

Vòng lặp sự kiện hoạt động theo các yêu cầu cụ thể để kiểm soát thứ tự thực hiện gọi lại. Mã Javascript đồng bộ của người dùng được ưu tiên khi bắt đầu quá trình, do đó vòng lặp sự kiện chỉ bắt đầu khi ngăn xếp cuộc gọi bị xóa. Trình tự thực hiện sau đây tuân theo một mẫu có cấu trúc:

Mức độ ưu tiên cao nhất được dành cho các lệnh gọi lại trong hàng đợi microtask, sau đó chuyển sang thực thi các tác vụ trong hàng đợi nextTick, sau đó là các tác vụ trong hàng đợi Promise. Sau đó, các quy trình trong lệnh gọi lại hàng đợi của bộ hẹn giờ sẽ được xử lý, sau đó hàng đợi vi nhiệm sẽ được truy cập lại sau mỗi lần gọi lại bộ hẹn giờ. Sau đó, các lệnh gọi lại trong hàng đợi I/O, kiểm tra và đóng sẽ được thực thi theo mẫu tương tự với hàng đợi vi nhiệm được truy cập sau mỗi giai đoạn.

Vòng lặp tiếp tục thực thi nếu có nhiều lệnh gọi lại cần xử lý. Khi tập lệnh mã đã kết thúc hoặc không còn lệnh gọi lại nào để xử lý, vòng lặp sự kiện sẽ kết thúc một cách hiệu quả.

Bây giờ chúng ta đã hiểu sâu về vòng lặp Sự kiện, hãy xem xét các tính năng của nó.

Các tính năng của vòng lặp sự kiện trong Node.js

Các tính năng chính là:

  • Vòng lặp sự kiện là một vòng lặp vô hạn và tiếp tục thực thi các tác vụ ngay khi nhận được chúng và chuyển sang chế độ ngủ trong trường hợp không có tác vụ nào nhưng bắt đầu hoạt động ngay khi nhận được tác vụ.
  • Các tác vụ trong hàng đợi sự kiện chỉ được thực thi khi ngăn xếp trống nghĩa là không có thao tác nào đang hoạt động.
  • Cuộc gọi lại và lời hứa có thể được sử dụng trong vòng lặp sự kiện.
  • Vì vòng lặp sự kiện tuân theo nguyên tắc hàng đợi kiểu dữ liệu trừu tượng, nó hoàn thành nhiệm vụ đầu tiên rồi chuyển sang nhiệm vụ tiếp theo.

Sau khi hiểu rõ về vòng lặp sự kiện cũng như logic của việc thực thi không đồng bộ và đồng bộ, việc hiểu rõ về các giai đoạn khác nhau có thể củng cố các khái niệm về vòng lặp sự kiện.

Các giai đoạn của vòng lặp sự kiện Node.js

Như đã đề cập ở trên, vòng lặp sự kiện là bán vô hạn. Nó có nhiều giai đoạn nhưng một số giai đoạn được sử dụng để xử lý nội bộ. Các giai đoạn này không có bất kỳ ảnh hưởng nào đến tập lệnh mã.

Vòng lặp sự kiện tuân theo chức năng của Hàng đợi và thực hiện tác vụ theo nguyên tắc nhập trước, xuất trước. Bộ hẹn giờ đã lên lịch sẽ được hệ điều hành xử lý cho đến khi hết hạn. Sau đó, bộ hẹn giờ đã hết hạn sẽ được thêm vào hàng đợi gọi lại cho bộ hẹn giờ.

Vòng lặp sự kiện thực hiện từng nhiệm vụ trong hàng đợi của bộ đếm thời gian cho đến khi không còn nhiệm vụ nào nữa hoặc đạt đến số lượng nhiệm vụ tối đa cho phép. Trong các phần bên dưới, các giai đoạn cốt lõi của vòng lặp sự kiện sẽ được giải thích.

Giai đoạn hẹn giờ

Trong Node.js có API hẹn giờ có thể lên lịch cho các chức năng sẽ được thực thi trong tương lai. Sau khi hết thời gian được phân bổ, lệnh gọi lại hẹn giờ sẽ thực thi ngay khi chúng có thể được lên lịch; tuy nhiên, có thể gặp phải sự chậm trễ từ phía hệ điều hành hoặc do việc thực hiện các lệnh gọi lại khác.

API bộ hẹn giờ có ba chức năng chính:

  • setTimeout
  • thiết lập ngay lập tức
  • tập khoảng thời gian

Các chức năng nêu trên là đồng bộ. Giai đoạn hẹn giờ trong vòng lặp sự kiện có phạm vi giới hạn ở các hàm setTimeout và setInterval. Trong khi hàm kiểm tra xử lý hàm setImmediate.

Hãy xem xét một ví dụ đơn giản để củng cố phần lý thuyết:

// ứng dụng.js

chức năng bị trì hoãnChức năng ( ) {

bảng điều khiển. nhật ký ( 'chức năng bị trì hoãn được thực thi sau khi hết thời gian' ) ;

}

bảng điều khiển. nhật ký ( 'Bắt đầu chương trình' ) ;

setTimeout ( chức năng bị trì hoãn, 2000 ) ;

bảng điều khiển. nhật ký ( 'Kết thúc chương trình' ) ;

Trong mã này:

  • Chương trình bắt đầu bằng cách ghi câu lệnh “Bắt đầu chương trình” vào thiết bị đầu cuối.
  • Sau đó, hàm bị trì hoãn được gọi với bộ đếm thời gian là 2 mili giây, tập lệnh mã không dừng lại và tiếp tục xử lý độ trễ ở chế độ nền.
  • Câu lệnh “Kết thúc Chương trình được ghi lại sau câu lệnh đầu tiên.
  • Sau độ trễ 2 mili giây, câu lệnh trong delayFunction sẽ được ghi vào thiết bị đầu cuối.

đầu ra

Đầu ra sẽ hiển thị dưới dạng:

Có thể thấy code không bị dừng lại để delayFunction xử lý; nó di chuyển về phía trước và sau độ trễ, hàm gọi lại được xử lý.

Cuộc gọi lại đang chờ xử lý

Vòng lặp sự kiện kiểm tra các sự kiện đang xảy ra, như đọc tệp, hoạt động mạng hoặc tác vụ đầu vào/đầu ra, trong giai đoạn thăm dò. Điều quan trọng cần biết là trong Node.js, chỉ một số sự kiện được xử lý trong giai đoạn thăm dò này. Tuy nhiên, trong lần lặp tiếp theo của vòng lặp sự kiện, một số sự kiện nhất định có thể được hoãn lại sang giai đoạn chờ xử lý. Đây là khái niệm quan trọng cần ghi nhớ khi tối ưu hóa và khắc phục sự cố mã Node.js liên quan đến các hoạt động theo hướng sự kiện phức tạp.

Điều quan trọng là phải hiểu rằng trong giai đoạn chờ lệnh gọi lại, vòng lặp sự kiện sẽ thêm các sự kiện bị hoãn vào hàng lệnh gọi lại đang chờ xử lý và thực hiện chúng. Giai đoạn này cũng xử lý một số lỗi TCP socket mà hệ thống đã phát sinh, chẳng hạn như các sự kiện lỗi ECONNREFUSED trên một số hệ điều hành nhất định.

Dưới đây một ví dụ được đề cập để củng cố khái niệm:

// ứng dụng.js
hằng số fs = yêu cầu ( 'fs' ) ;
chức năng readFileAsync ( filePath, gọi lại ) {
fs. Đọc tài liệu ( './PromiseText.txt' , 'utf8' , chức năng ( lỗi, dữ liệu ) {
nếu như ( lỗi ) {
bảng điều khiển. lỗi ( ` Lỗi đọc tập tin : $ { lỗi. tin nhắn } ` ) ;
} khác {
bảng điều khiển. nhật ký ( ` Tài liệu nội dung : $ { dữ liệu } ` ) ;
}
gọi lại ( ) ;
} ) ;
}
bảng điều khiển. nhật ký ( 'Bắt đầu chương trình' ) ;
readFileAsync ( './PromiseText.txt' , chức năng ( ) {
bảng điều khiển. nhật ký ( 'Thực thi lệnh gọi lại đọc tệp' ) ;
} ) ;
bảng điều khiển. nhật ký ( 'Kết thúc chương trình' ) ;

Trong mã này:

  • Chương trình được bắt đầu bằng cách ghi lại câu lệnh “Bắt đầu chương trình” trong thiết bị đầu cuối.
  • ReadFileAsync được xác định không đồng bộ để đọc nội dung của tệp “PromiseText.txt”. Đây là một hàm được tham số hóa, thực thi hàm gọi lại sau khi tệp được đọc.
  • Hàm readFileAsync được gọi để bắt đầu quá trình đọc tệp.
  • Trong quá trình đọc file, chương trình không dừng lại; thay vào đó, nó chuyển sang câu lệnh tiếp theo và ghi nó vào terminal “Kết thúc chương trình”.
  • Sự kiện đọc tệp không đồng bộ được xử lý ở chế độ nền bởi vòng lặp sự kiện.
  • Sau khi tệp được đọc không đồng bộ và nội dung đã được ghi vào thiết bị đầu cuối, chương trình sẽ ghi nội dung tệp vào thiết bị đầu cuối. Sau đó, nó ghi lại thông báo sau “Đã thực hiện gọi lại đã đọc tệp”.
  • Vòng lặp sự kiện xử lý các hoạt động gọi lại đang chờ xử lý trong giai đoạn tiếp theo.

đầu ra

Kết quả của việc thực hiện trên là:

Giai đoạn nhàn rỗi, chuẩn bị trong Node.js

Giai đoạn nhàn rỗi được sử dụng để xử lý các chức năng nội bộ trong Node.js nên đây không phải là giai đoạn tiêu chuẩn. Nó không ảnh hưởng đến tập lệnh mã. Giai đoạn nhàn rỗi giống như khoảng thời gian nghỉ cho vòng lặp sự kiện trong đó quản lý các tác vụ có mức độ ưu tiên thấp ở chế độ nền. Một ví dụ đơn giản để hiểu giai đoạn này là:

hằng số { nhàn rỗi } = yêu cầu ( 'nhàn rỗi-gc' ) ;

nhàn rỗi. phớt lờ ( ) ;

Trong mã này, mô-đun “idle-gc” được sử dụng cho phép bỏ qua giai đoạn không hoạt động. Điều này dùng để xử lý các tình huống khi vòng lặp sự kiện bận và các tác vụ nền không được thực hiện. Việc sử dụng Idle.ignore không được coi là tối ưu vì nó có thể gây ra các vấn đề về hiệu suất.

Giai đoạn bỏ phiếu trong Node.js

Giai đoạn thăm dò ý kiến ​​trong Node.js đóng vai trò:

  • Nó xử lý các sự kiện trong hàng đợi thăm dò và thực hiện các nhiệm vụ tương ứng của chúng.
  • Nó quyết định lượng thời gian chờ đợi và kiểm tra các hoạt động I/O trong quy trình.

Khi vòng lặp sự kiện bước vào giai đoạn thăm dò do không có bộ đếm thời gian, một trong các tác vụ dưới đây sẽ được thực hiện:

  • Trong giai đoạn thăm dò của vòng lặp sự kiện trong Node.js, các sự kiện I/O đang chờ xử lý được xếp hàng đợi và sau đó được thực thi theo quy trình tuần tự theo nguyên tắc Vào trước và Ra trước cho đến khi hàng đợi trống. Trong quá trình thực thi lệnh gọi lại, hàng đợi nextTick và microtasks cũng hoạt động. Điều này đảm bảo sự trơn tru và cho phép xử lý các hoạt động I/O hiệu quả và đáng tin cậy hơn.
  • Nếu hàng đợi trống và tập lệnh chưa được hàm setImmediate() lên lịch thì vòng lặp sự kiện sẽ kết thúc và nó sẽ chuyển sang giai đoạn tiếp theo (kiểm tra). Mặt khác, nếu việc lập lịch tập lệnh đã được thực hiện bởi hàm setImmediate() thì vòng lặp sự kiện sẽ cho phép các lệnh gọi lại được thêm vào hàng đợi sẽ được nó thực thi.

Điều này được minh họa rõ nhất bằng một ví dụ mã đơn giản:

setTimeout ( ( ) => {

bảng điều khiển. nhật ký ( 'Hoạt động không đồng bộ đã hoàn tất' ) ;

} , 2000 ) ;

bảng điều khiển. nhật ký ( 'Bắt đầu' ) ;

thiết lập ngay lập tức ( ( ) => {

bảng điều khiển. nhật ký ( 'gọi lại setIngay lập tức được thực hiện' ) ;

} ) ;

bảng điều khiển. nhật ký ( 'Kết thúc' ) ;

Trong mã này:

  • Hai thông báo “Bắt đầu” và “Kết thúc” cho biết việc bắt đầu và kết thúc chương trình.
  • Hàm setTimeout() đặt chức năng gọi lại với độ trễ là 2 ms và ghi nhật ký “Đã hoàn thành thao tác Async” vào thiết bị đầu cuối.
  • Hàm setImmediate() ghi thông báo “setImmediate callback done” vào thiết bị đầu cuối sau khi thông báo Bắt đầu được ghi vào thiết bị đầu cuối.

đầu ra

Đầu ra sẽ hiển thị các thông báo chỉ với một phút quan sát rằng “Hoạt động không đồng bộ đã hoàn thành” cần có thời gian và được in sau thông báo “Kết thúc”:

Giai đoạn kiểm tra Node.js

Sau khi giai đoạn thăm dò được thực hiện, các cuộc gọi lại trong giai đoạn kiểm tra sẽ được thực thi. Nếu tập lệnh mã được lên lịch bằng hàm setImmediate() và hàm thăm dò được rảnh, vòng lặp sự kiện sẽ hoạt động bằng cách chuyển trực tiếp sang giai đoạn kiểm tra thay vì ở chế độ chờ. Hàm setImmediate() là một bộ đếm thời gian duy nhất hoạt động trong các giai đoạn khác nhau của vòng lặp sự kiện.

API libuv được sử dụng để lập kế hoạch thực hiện cuộc gọi lại sau khi hoàn thành quá trình thực hiện giai đoạn thăm dò ý kiến. Trong quá trình thực thi mã, vòng lặp sự kiện bước vào giai đoạn thăm dò trong đó nó chờ các yêu cầu kết nối đến. Trong trường hợp khác, nếu cuộc gọi lại được lên lịch bằng hàm setImmediate() và giai đoạn thăm dò kết thúc mà không có bất kỳ hoạt động nào thì nó sẽ chuyển sang giai đoạn kiểm tra thay vì chờ đợi. Hãy xem xét ví dụ dưới đây để hiểu:

// ứng dụng.js

bảng điều khiển. nhật ký ( 'Bắt đầu' ) ;

thiết lập ngay lập tức ( ( ) => {

bảng điều khiển. nhật ký ( 'Gọi lại ngay lập tức' ) ;

} ) ;

bảng điều khiển. nhật ký ( 'Kết thúc' ) ;

Trong mã này, ba tin nhắn được đăng nhập vào thiết bị đầu cuối. Cuối cùng, hàm setImmediate() sẽ gửi một lệnh gọi lại để ghi thông báo “ Gọi lại ngay lập tức ” đến thiết bị đầu cuối.

đầu ra

Đầu ra của đoạn mã trên sẽ hiển thị theo trình tự sau:

Node.js đóng lệnh gọi lại

Node.js sử dụng giai đoạn đóng này để chạy lệnh gọi lại nhằm đóng các sự kiện và kết thúc vòng lặp sự kiện. Sau khi kết nối được đóng, vòng lặp sự kiện sẽ xử lý các sự kiện kết thúc trong giai đoạn này. Trong giai đoạn này của vòng lặp sự kiện, “nextTick()” và các tác vụ vi mô được tạo và xử lý tương tự như các giai đoạn khác.

Hàm process.exit được sử dụng để kết thúc vòng lặp sự kiện bất cứ lúc nào. Vòng lặp sự kiện sẽ bỏ qua mọi hoạt động không đồng bộ đang chờ xử lý và quá trình Node.js sẽ chấm dứt.

Một ví dụ đơn giản để xem xét là:

// ứng dụng.js
hằng số mạng lưới = yêu cầu ( 'mạng lưới' ) ;
hằng số máy chủ = mạng lưới. máy chủ tạo ( ( ổ cắm ) => {
ổ cắm. TRÊN ( 'đóng' , ( ) => {
bảng điều khiển. nhật ký ( 'Ổ cắm đã đóng' ) ;
} ) ;
ổ cắm. TRÊN ( 'dữ liệu' , ( dữ liệu ) => {
bảng điều khiển. nhật ký ( 'Dữ liệu đã nhận:' , dữ liệu. toString ( ) ) ;
} ) ;
} ) ;
máy chủ. TRÊN ( 'đóng' , ( ) => {
bảng điều khiển. nhật ký ( 'Đong may chủ' ) ;
} ) ;
hằng số Hải cảng = 3000 ;
máy chủ. Nghe ( Hải cảng, ( ) => {
bảng điều khiển. nhật ký ( `Máy chủ đang nghe trên cổng $ { Hải cảng } ` ) ;
} ) ;
setTimeout ( ( ) => {
bảng điều khiển. nhật ký ( 'Đóng máy chủ sau 10 giây' ) ;
máy chủ. đóng ( ) ;
quá trình. lối ra ( ) ;
} , 10000 ) ;

Trong mã này:

  • const net = require('net') ” nhập mô-đun mạng cần thiết để xử lý máy chủ TCP và “ máy chủ const = net.createServer((socket) => { ” tạo một phiên bản máy chủ TCP mới.
  • socket.on('đóng', () => {… } ” lắng nghe tiếng “đóng” trên tất cả các ổ cắm. Khi kết nối ổ cắm bị đóng, thông báo “Socket Closed” được ghi vào thiết bị đầu cuối.
  • socket.on('data', (data) => {} ” kiểm tra dữ liệu đến từ tất cả các ổ cắm riêng lẻ và in dữ liệu đó bằng hàm “.toString()”.
  • server.on(‘close’, () => {…} ” kiểm tra sự kiện “đóng” trên chính máy chủ và khi kết nối máy chủ bị đóng, nó sẽ ghi thông báo “Đã đóng máy chủ” vào thiết bị đầu cuối.
  • server.listen(port, () => {…} ” lắng nghe các kết nối đến trên cổng.
  • setTimeout(() => {…} ” đặt bộ hẹn giờ 10 ms để đóng máy chủ.

Điều đó kết thúc cuộc thảo luận về các giai đoạn khác nhau của vòng lặp sự kiện trong Node.js. Trước khi đi đến kết luận, hãy thảo luận một điều cuối cùng đó là cách thoát khỏi vòng lặp sự kiện trong Node.js.

Thoát khỏi vòng lặp sự kiện trong Node.js

Vòng lặp sự kiện đang trong giai đoạn thực thi miễn là có một số tác vụ trong tất cả các hàng đợi của các giai đoạn vòng lặp sự kiện. Vòng lặp sự kiện kết thúc sau khi giai đoạn thoát được phát ra và lệnh gọi lại trình xử lý thoát sẽ trả về nếu không còn tác vụ nào trong hàng đợi.

Cách rõ ràng để kết thúc vòng lặp sự kiện là sử dụng phương thức “.exit”. Các quy trình đang hoạt động của Node.js sẽ chấm dứt ngay lập tức ngay khi hàm process.exit được gọi. Tất cả các sự kiện đã lên lịch và đang chờ xử lý sẽ bị loại bỏ:

quá trình. TRÊN ( 'lối ra' , ( mã số ) => {

bảng điều khiển. nhật ký ( `Thoát bằng mã thoát : $ { mã số } ` ) ;

} ) ;

quá trình. lối ra ( 1 ) ;

Người dùng có thể nghe chức năng .exit. Cần lưu ý rằng hàm “.exit” phải đồng bộ vì chương trình Node.js sẽ thoát ngay khi nghe sự kiện này.

Điều này kết thúc cuộc thảo luận về vòng lặp sự kiện. Một bài viết chuyên sâu đề cập đến tất cả các khái niệm, giai đoạn và ví dụ liên quan đến vòng lặp sự kiện.

Phần kết luận

Trước khi hiểu vòng lặp sự kiện, tổng quan về các khái niệm đồng bộ và không đồng bộ có thể giúp hiểu được luồng mã trong vòng lặp sự kiện. Thực thi đồng bộ có nghĩa là thực hiện từng bước trong khi thực thi không đồng bộ có nghĩa là tạm dừng một số bước mà không cần đợi chúng hoàn thành. Hoạt động của vòng lặp sự kiện cùng với tất cả các giai đoạn cùng với các ví dụ phù hợp sẽ được thảo luận trong bài viết.