Làm thế nào NodeJS có thể không bị chặn thành công?


14

Tôi đang học NodeJS và chỉ muốn làm rõ điều gì đó. Trong một số hướng dẫn và sách giới thiệu cho đến nay, từ rất sớm họ đã mô tả kiến ​​trúc "không chặn" của Node - hay đúng hơn là có thể (và được khuyến nghị, toàn bộ điểm) để viết mã theo cách không chặn.

Vì vậy, ví dụ, ví dụ này đã được đưa ra trong một cuốn sách tôi đang đọc về một cách không đồng bộ để lấy dữ liệu từ cơ sở dữ liệu.

http.createServer(function (req, res) {
  database.getInformation(function (data) {
      res.writeHead(200);
      res.end(data);
  });
});

Điều xảy ra (theo tôi hiểu) là Node thực hiện cuộc gọi đến cơ sở dữ liệu, sau đó tiếp tục xử lý bất cứ điều gì có thể tiếp theo trên ngăn xếp cuộc gọi. Khi yêu cầu cơ sở dữ liệu hoàn tất, biến dữ liệu trong hàm gọi lại ẩn danh sẽ được điền và hàm đó được thêm vào ngăn xếp cuộc gọi (và sau đó được thực thi khi Node đến nó).

Câu hỏi của tôi là, chính xác những gì đang xử lý yêu cầu cơ sở dữ liệu? Chắc chắn Node phải chặn trong khi nó làm điều đó? Điều gì đang chăm sóc yêu cầu cơ sở dữ liệu? Hoặc nếu Node đang chờ một yêu cầu HTTP GET không đồng bộ với tài nguyên bên ngoài, thì điều gì quan tâm đến yêu cầu đó cho phép Node tiếp tục xử lý ngăn xếp cuộc gọi và "không chặn"?

Câu trả lời:


17

Khi Node.js được mô tả là "không chặn", điều đó có nghĩa cụ thể là IO của nó không chặn. Node sử dụng libuv để xử lý IO của nó theo cách không dựa trên nền tảng. Trên Windows, nó sử dụng các cổng hoàn thành IO, trên Unix, nó sử dụng epoll / kqueue / select / etc. Vì vậy, nó thực hiện một yêu cầu IO không chặn (có thể có giám sát luồng nền, nhưng điều này không bao giờ được hiển thị với JavaScript) và kết quả là, nó xếp hàng nó trong vòng lặp sự kiện gọi hàm gọi lại JavaScript trên chính (đọc: chỉ) Chuỗi JavaScript.

Đối với cơ sở dữ liệu, nó phụ thuộc vào cách thư viện được viết. Nếu nó sử dụng HTTP để giao tiếp (như một số cơ sở dữ liệu NoQuery làm), thì nó có thể dễ dàng được viết bằng JavaScript thuần bằng httpthư viện nút tiêu chuẩn . Nếu nó làm theo cách khác, tốt, đó là tùy thuộc vào thư viện. Nó có thể được viết bằng C / C ++ và sử dụng các luồng nền miễn là sự trừu tượng đó không bao giờ được hiển thị với JavaScript.

Đối với câu hỏi của bạn về "xử lý" yêu cầu cơ sở dữ liệu là gì, lý tưởng nhất là tất cả những gì nên làm là gửi một tin nhắn đơn giản đến thư viện (ví dụ: câu lệnh SQL hoặc một số truy vấn khác hoặc yêu cầu kết nối) và tại thời điểm đó, JavaScript của bạn tiếp tục đi Khi thư viện sẵn sàng gửi tin nhắn trở lại, nó sẽ gửi tin nhắn trở lại hàng đợi sự kiện của nút để chạy lại cuộc gọi, cho phép đoạn mã đó chạy.


netgói khi http không có sẵn.
Florian Margaine

Chi tiết có thể giúp. Node tận dụng động cơ V8 JS. Một trong những tính năng tốt nhất của V8 là dễ dàng ràng buộc các quy trình C / C ++ với các cuộc gọi JS. Các hàm JavaScript đang chặn nhưng tất cả các hàm thực hiện là gọi một cái gì đó bên dưới mui xe không chặn. Sau đó, một hàm JS khác đáp ứng khi quá trình đó được thực hiện. Các hàm JS chặn lẫn nhau có nghĩa là bạn sẽ không bao giờ có hai việc cố gắng làm một việc gì đó như lên lịch ghi vào cùng một vị trí tệp cùng một lúc mà tôi cho rằng cần phải quản lý nhiều luồng. Luôn luôn rõ ràng yêu cầu nào được đưa ra đầu tiên cho mục đích xếp hàng.
Erik Reppen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.