Vòng lặp sự kiện NodeJS

JavaScript có mô hình thời gian chạy dựa trên vòng lặp sự kiện, chịu trách nhiệm thực thi mã, thu thập và xử lý sự kiện cũng như thực hiện các tác vụ phụ được xếp hàng đợi. Mô hình này khá khác so với các mô hình trong các ngôn ngữ khác như C và Java

khái niệm thời gian chạy

Các phần sau đây giải thích một mô hình lý thuyết. Các công cụ JavaScript hiện đại triển khai và tối ưu hóa mạnh mẽ ngữ nghĩa được mô tả

Đại diện trực quan

Vòng lặp sự kiện NodeJS

Cây rơm

Các lời gọi hàm tạo thành một ngăn xếp các khung

function foo(b) {
  const a = 10;
  return a + b + 11;
}

function bar(x) {
  const y = 3;
  return foo(x * y);
}

const baz = bar(7); // assigns 42 to baz

Thứ tự các thao tác

  1. Khi gọi
    while (queue.waitForMessage()) {
      queue.processNextMessage();
    }
    
    8, khung đầu tiên được tạo có chứa tham chiếu đến các đối số và biến cục bộ của
    while (queue.waitForMessage()) {
      queue.processNextMessage();
    }
    
    8
  2. Khi
    while (queue.waitForMessage()) {
      queue.processNextMessage();
    }
    
    8 gọi
    while (queue.waitForMessage()) {
      queue.processNextMessage();
    }
    
    1, khung thứ hai được tạo và đẩy lên trên khung đầu tiên, chứa tham chiếu đến các đối số và biến cục bộ của
    while (queue.waitForMessage()) {
      queue.processNextMessage();
    }
    
    1
  3. Khi
    while (queue.waitForMessage()) {
      queue.processNextMessage();
    }
    
    1 trả về, phần tử khung trên cùng được bật ra khỏi ngăn xếp (chỉ để lại khung gọi của
    while (queue.waitForMessage()) {
      queue.processNextMessage();
    }
    
    8)
  4. Khi
    while (queue.waitForMessage()) {
      queue.processNextMessage();
    }
    
    8 trở lại, ngăn xếp trống

Lưu ý rằng các đối số và biến cục bộ có thể tiếp tục tồn tại vì chúng được lưu trữ bên ngoài ngăn xếp — vì vậy chúng có thể được truy cập bởi bất kỳ hàm lồng nhau nào sau khi hàm bên ngoài của chúng đã trả về

đống

Các đối tượng được phân bổ trong một đống chỉ là một tên để biểu thị một vùng bộ nhớ lớn (hầu hết không có cấu trúc)

Xếp hàng

Thời gian chạy JavaScript sử dụng hàng đợi tin nhắn, là danh sách các tin nhắn sẽ được xử lý. Mỗi tin nhắn có một chức năng liên quan được gọi để xử lý tin nhắn

Tại một thời điểm nào đó trong vòng lặp sự kiện, bộ thực thi bắt đầu xử lý các thông báo trên hàng đợi, bắt đầu với thông báo cũ nhất. Để làm như vậy, thông báo sẽ bị xóa khỏi hàng đợi và chức năng tương ứng của nó được gọi với thông báo là tham số đầu vào. Như thường lệ, việc gọi một hàm sẽ tạo một khung ngăn xếp mới để sử dụng hàm đó

Quá trình xử lý các chức năng tiếp tục cho đến khi ngăn xếp trống một lần nữa. Sau đó, vòng lặp sự kiện sẽ xử lý thông báo tiếp theo trong hàng đợi (nếu có)

vòng lặp sự kiện

Vòng lặp sự kiện có tên như vậy vì cách nó thường được triển khai, thường giống như

while (queue.waitForMessage()) {
  queue.processNextMessage();
}

while (queue.waitForMessage()) {
  queue.processNextMessage();
}
2 chờ một tin nhắn đến một cách đồng bộ (nếu một tin nhắn chưa có sẵn và đang chờ xử lý)

"Chạy đến khi hoàn thành"

Mỗi tin nhắn được xử lý hoàn toàn trước khi bất kỳ tin nhắn nào khác được xử lý

Điều này cung cấp một số thuộc tính hay khi lập luận về chương trình của bạn, bao gồm thực tế là bất cứ khi nào một chức năng chạy, nó không thể được ưu tiên và sẽ chạy hoàn toàn trước khi bất kỳ mã nào khác chạy (và có thể sửa đổi dữ liệu mà chức năng thao tác). Điều này khác với C, chẳng hạn, ở chỗ nếu một hàm chạy trong một luồng, thì nó có thể bị dừng tại bất kỳ thời điểm nào bởi hệ thống thời gian chạy để chạy một số mã khác trong một luồng khác

Nhược điểm của mô hình này là nếu một thông báo mất quá nhiều thời gian để hoàn thành, ứng dụng web không thể xử lý các tương tác của người dùng như nhấp hoặc cuộn. Trình duyệt giảm thiểu điều này bằng hộp thoại "tập lệnh mất quá nhiều thời gian để chạy". Một thực hành tốt để làm theo là làm cho quá trình xử lý tin nhắn trở nên ngắn gọn và nếu có thể, hãy cắt một tin nhắn thành nhiều tin nhắn

Thêm tin nhắn

Trong trình duyệt web, các thông báo được thêm vào bất cứ khi nào một sự kiện xảy ra và có một trình xử lý sự kiện được đính kèm với nó. Nếu không có người nghe, sự kiện sẽ bị mất. Vì vậy, một lần nhấp vào một phần tử có trình xử lý sự kiện nhấp chuột sẽ thêm một thông báo — tương tự như vậy với bất kỳ sự kiện nào khác

Hàm

while (queue.waitForMessage()) {
  queue.processNextMessage();
}
3 được gọi với 2 đối số. một thông báo để thêm vào hàng đợi và một giá trị thời gian (tùy chọn; mặc định là
while (queue.waitForMessage()) {
  queue.processNextMessage();
}
4). Giá trị thời gian biểu thị độ trễ (tối thiểu) sau đó tin nhắn sẽ được đẩy vào hàng đợi. Nếu không có tin nhắn nào khác trong hàng đợi và ngăn xếp trống, tin nhắn sẽ được xử lý ngay sau khi trì hoãn. Tuy nhiên, nếu có các tin nhắn, tin nhắn
while (queue.waitForMessage()) {
  queue.processNextMessage();
}
3 sẽ phải chờ các tin nhắn khác xử lý. Vì lý do này, đối số thứ hai chỉ ra thời gian tối thiểu — không phải là thời gian đảm bảo

Đây là một ví dụ thể hiện khái niệm này (

while (queue.waitForMessage()) {
  queue.processNextMessage();
}
3 không chạy ngay sau khi hết giờ)

const seconds = new Date().getTime() / 1000;

setTimeout(() => {
  // prints out "2", meaning that the callback is not called immediately after 500 milliseconds.
  console.log(`Ran after ${new Date().getTime() / 1000 - seconds} seconds`);
}, 500)

while (true) {
  if (new Date().getTime() / 1000 - seconds >= 2) {
    console.log("Good, looped for 2 seconds");
    break;
  }
}

Không chậm trễ

Độ trễ bằng 0 không có nghĩa là cuộc gọi lại sẽ tắt sau 0 mili giây. Gọi

while (queue.waitForMessage()) {
  queue.processNextMessage();
}
3 với độ trễ của
while (queue.waitForMessage()) {
  queue.processNextMessage();
}
4 (không) mili giây không thực thi chức năng gọi lại sau khoảng thời gian đã cho

Việc thực thi phụ thuộc vào số lượng tác vụ đang chờ trong hàng đợi. Trong ví dụ bên dưới, thông báo

while (queue.waitForMessage()) {
  queue.processNextMessage();
}
9 sẽ được ghi vào bảng điều khiển trước khi thông báo trong hàm gọi lại được xử lý, vì độ trễ là thời gian tối thiểu cần thiết để bộ thực thi xử lý yêu cầu (không phải là thời gian đảm bảo)

while (queue.waitForMessage()) {
  queue.processNextMessage();
}
3 cần đợi tất cả mã cho các tin nhắn được xếp hàng đợi hoàn tất mặc dù bạn đã chỉ định giới hạn thời gian cụ thể cho
while (queue.waitForMessage()) {
  queue.processNextMessage();
}
3 của mình

while (queue.waitForMessage()) {
  queue.processNextMessage();
}
3

Một số thời gian chạy giao tiếp với nhau

Một nhân viên web hoặc một

const seconds = new Date().getTime() / 1000;

setTimeout(() => {
  // prints out "2", meaning that the callback is not called immediately after 500 milliseconds.
  console.log(`Ran after ${new Date().getTime() / 1000 - seconds} seconds`);
}, 500)

while (true) {
  if (new Date().getTime() / 1000 - seconds >= 2) {
    console.log("Good, looped for 2 seconds");
    break;
  }
}
2 có nguồn gốc chéo có hàng đợi ngăn xếp, đống và tin nhắn riêng. Hai thời gian chạy riêng biệt chỉ có thể giao tiếp thông qua việc gửi tin nhắn qua phương thức
const seconds = new Date().getTime() / 1000;

setTimeout(() => {
  // prints out "2", meaning that the callback is not called immediately after 500 milliseconds.
  console.log(`Ran after ${new Date().getTime() / 1000 - seconds} seconds`);
}, 500)

while (true) {
  if (new Date().getTime() / 1000 - seconds >= 2) {
    console.log("Good, looped for 2 seconds");
    break;
  }
}
3. Phương pháp này thêm một thông báo vào thời gian chạy khác nếu thời gian chạy sau lắng nghe các sự kiện
const seconds = new Date().getTime() / 1000;

setTimeout(() => {
  // prints out "2", meaning that the callback is not called immediately after 500 milliseconds.
  console.log(`Ran after ${new Date().getTime() / 1000 - seconds} seconds`);
}, 500)

while (true) {
  if (new Date().getTime() / 1000 - seconds >= 2) {
    console.log("Good, looped for 2 seconds");
    break;
  }
}
4

không bao giờ chặn

Một thuộc tính rất thú vị của mô hình vòng lặp sự kiện là JavaScript, không giống như nhiều ngôn ngữ khác, không bao giờ chặn. Việc xử lý I/O thường được thực hiện thông qua các sự kiện và lệnh gọi lại, vì vậy khi ứng dụng đang chờ truy vấn IndexedDB trả về hoặc yêu cầu XHR trả về, ứng dụng vẫn có thể xử lý những thứ khác như đầu vào của người dùng

Các ngoại lệ kế thừa tồn tại như

const seconds = new Date().getTime() / 1000;

setTimeout(() => {
  // prints out "2", meaning that the callback is not called immediately after 500 milliseconds.
  console.log(`Ran after ${new Date().getTime() / 1000 - seconds} seconds`);
}, 500)

while (true) {
  if (new Date().getTime() / 1000 - seconds >= 2) {
    console.log("Good, looped for 2 seconds");
    break;
  }
}
5 hoặc XHR đồng bộ, nhưng nên tránh chúng. coi chừng. ngoại lệ đối với ngoại lệ tồn tại (nhưng thường là lỗi triển khai, chứ không phải bất kỳ lỗi nào khác)

Vòng lặp sự kiện trong NodeJS là gì?

Vòng lặp sự kiện là một vòng lặp vô tận, chờ các tác vụ, thực thi chúng rồi ngủ cho đến khi nhận được nhiều tác vụ hơn . Vòng lặp sự kiện chỉ thực thi các tác vụ từ hàng đợi sự kiện khi ngăn xếp cuộc gọi trống i. e. không có nhiệm vụ đang diễn ra. Vòng lặp sự kiện cho phép chúng tôi sử dụng các cuộc gọi lại và lời hứa.

NodeJS có vòng lặp sự kiện không?

Vòng lặp sự kiện là thứ cho phép Node. js để thực hiện các thao tác I/O không chặn — mặc dù thực tế là JavaScript là một luồng — bằng cách giảm tải các thao tác cho nhân hệ thống bất cứ khi nào có thể. Vì hầu hết các kernel hiện đại đều đa luồng, chúng có thể xử lý nhiều thao tác thực thi trong nền.

Vòng lặp sự kiện trong js là gì?

Vòng lặp sự kiện. Một vòng lặp sự kiện là thứ gì đó lấy nội dung ra khỏi hàng đợi và đặt nó vào ngăn xếp thực thi chức năng bất cứ khi nào ngăn xếp chức năng trống .

Làm thế nào để vòng lặp sự kiện Node hoạt động nội bộ?

Vòng lặp sự kiện lấy bộ đếm thời gian có thời gian chờ ngắn nhất và so sánh nó với thời gian hiện tại của Vòng lặp sự kiện . Nếu thời gian chờ đã trôi qua, thì cuộc gọi lại của bộ đếm thời gian sẽ được xếp hàng đợi để được gọi sau khi ngăn xếp cuộc gọi trống. Nút. js có các loại bộ hẹn giờ khác nhau. setTimeout() và setInterval().