我們都知道NodeJS是單執行緒的,這意味著如果我們的代碼中有一個異步/等待操作,節點將在執行其他代碼之前等待它完成。因此,如果一個用戶提出了一個異步請求,其他用戶在提出請求之前也應該等待它完成。
在這里我創建了一個簡單的例子,第一條路由使用了一個異步函式,它在發送回應之前需要10秒,而第二條路由則立即發送了一個回應。
當我向第一個路由發送請求,在等待回應時,我向第二個路由發送了另一個請求,盡管第一個路由還沒有完成代碼的執行,我還是得到了一個回應。
為什么在這個例子中是非阻塞的呢?
function sleep(){
return new Promise((resolve,reject)=> {
setTimeout(()=>/span>{
resolve(true)
},10000)
}).then(val=>/span>val)
}
router.get('/route1',async(req,res)=>{
const test = await sleep()
res.send('HELLO WORLD'/span>)
})
router.get('/route2',(req,res)=> /span>{
res.send("HELLO WORLD"/span>)
})
uj5u.com熱心網友回復:
await只阻止/暫停當前函式的執行,而不是整個解釋器。 事實上,在一個函式內部擊中第一個await的時候,該函式立即回傳一個承諾,而該函式之后的其他處理(或其他事件的發生)可以自由運行。
因此,在你的例子中,當它碰到await sleep()時,該函式的執行被暫停,直到await決議/拒絕,并且包含async的函式立即回傳一個未完成的承諾。 由于使用router.get()的Express沒有對回傳的承諾做任何事情,它只是忽略了它并將控制權回傳到事件回圈。 稍后,你的第二個請求到達了服務器,一個事件被放入了nodejs的事件佇列,Express被這個事件呼叫,并為你的第二個路由處理程式服務。
所以,如果一個用戶發出了一個異步請求,其他用戶也應該在發出請求之前等待它完成?
不。只有那個包含await的請求處理程式的一個實體被暫停。 解釋器中的其他執行和通過事件回圈的其他事件處理程式(比如其他傳入的請求)仍然可以發生,所以其他請求仍然可以被處理,即使一個請求處理程式坐在await。 這說明了await是如何不阻塞或暫停整個解釋器的,只是一個函式的執行。
當我向第一個路由發送請求,在等待回應時,我向第二個路由發送了另一個請求,盡管第一個路由還沒有完成執行代碼,我還是得到了一個回應。為什么在這個例子上是非阻塞的呢?
只有第一個路由被await暫停。 其他事件和其他傳入的請求仍然可以被正常處理。
uj5u.com熱心網友回復:
NodeJs不是單執行緒。 你可以通過以下步驟進行檢查:
創建一個js檔案,然后運行它:
while(true)
while(true)
在終端上執行這個命令,以獲得運行這個js檔案的執行緒數。
NUM=ps M <pid> | wc -l && echo thread number is: $((NUM-1))
而且你可以看到,while(true)使用了超過1個執行緒。
讓我們移回你的代碼。
當你對/route1的請求尚未完成時,你可以立即得到對/route2的請求結果,這是因為NodeJs使用EventLoop來使異步函式不阻塞主執行緒。
當你呼叫sleep函式時,NodeJs將啟動一個定時器,然后將你的回呼從呼叫堆疊中取出(這就是為什么對/route2的請求不會被/route1阻塞),而當你的定時器被取出時,resolve(true)將被放入EventQueue,并且在EventLoop的幫助下,你在route1的回呼將被執行。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/327651.html
標籤:
上一篇:展開QChartView
