我將用這個簡單的例子來說明我的問題。令我驚訝的是為什么服務器永遠不會被創建并且套接字永遠不會被列印。如果我要洗掉 while 回圈,一切正常。我必須改變什么才能使下面的示例起作用?
const net = require('net');
net.createServer(socket => {
socket.setEncoding('utf-8');
console.log(socket);
}).listen(4242, '127.0.0.1');
console.log('do some while logic here')
while(true) { }
uj5u.com熱心網友回復:
發生這種情況是因為您的套接字創建不是一個即時程序。它需要進行系統呼叫等。換句話說,它是異步的。javascript 的作業方式是它具有主回圈和回呼佇列。基本上主回圈是執行的內容,回呼佇列是等待執行的內容(請參閱此https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop上的 MDN 檔案)。
在您的情況下發生的是您的回呼進入回呼佇列并等待執行,但它永遠不會這樣做,因為您的主回圈被while (true) {}回圈阻塞。如果您想要非阻塞行為,則需要將 while 回圈內部的內容發送到回呼佇列。在 javascript 中執行此操作的方法之一是使用setTimeout. 例如
const net = require('net');
net.createServer(socket => {
socket.setEncoding('utf-8');
console.log(socket);
}).listen(4242, '127.0.0.1');
console.log('do some while logic here')
function main() {
// do something here
setTimeout(main);
}
main()
這樣,您將不會遇到堆疊溢位問題,并且您會在 while 回圈中獲得非阻塞行為。
uj5u.com熱心網友回復:
Nodejs 是一個事件驅動的系統,它運行你的 Javascript 單執行緒。這意味著,為了讓事情正常作業,你不能在一個while()回圈(或任何其他型別的回圈)中占用整個 CPU,除非回圈直接包含一個await正在等待與異步操作相關的實際承諾的陳述句。
這是 nodejs 編程的基本原則,您必須學習如何將程式邏輯構建到事件驅動的世界中。你沒有展示你真正想要做什么,但是在一個緊密的回圈中“輪詢”任何東西通常不是撰寫事件驅動系統的正確方法。
因此,在您在此處顯示的代碼中:
const net = require('net');
net.createServer(socket => {
socket.setEncoding('utf-8');
console.log(socket);
}).listen(4242, '127.0.0.1');
console.log('do some while logic here')
while(true) { }
您的while回圈永遠旋轉,并且永遠不允許處理任何事件,因此您的服務器永遠無法獲取有關傳入連接的事件。這些事件只會堆積在事件佇列中,但您永遠不會讓 nodejs 有機會回傳事件佇列來處理這些事件。為此,您必須完成您正在做的事情并將控制權回傳給系統(這就是為什么您不能使用while(true) { }回圈的原因)。
所以,你真的需要考慮 nodejs 中的事件驅動編程。您設定事件偵聽器并在將來發生這些事件時執行代碼。setTimeout()您可以使用or人為地創建事件setInterval(),但是不斷地或非常非常短的持續時間只是輪詢,也不是對 nodejs 服務器進行編程的有效方法。
如果您向我們展示或描述您在其余代碼中真正想要做什么,我們可以建議這個問題中最重要的部分,即如何以事件驅動的方式實際撰寫該代碼。
我再說一遍,學習如何以事件驅動的方式編程是高效、可擴展的 nodejs 服務器行程所必需的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/411562.html
標籤:
