[英]NodeJS Event Loop Multiple Request
我對以下代碼有疑問(來源: https : //blog.risingstack.com/node-js-at-scale-understanding-node-js-event-loop/ ):
'use strict'
const express = require('express')
const superagent = require('superagent')
const app = express()
app.get('/', sendWeatherOfRandomCity)
function sendWeatherOfRandomCity (request, response) {
getWeatherOfRandomCity(request, response)
sayHi()
}
const CITIES = [
'london',
'newyork',
'paris',
'budapest',
'warsaw',
'rome',
'madrid',
'moscow',
'beijing',
'capetown',
]
function getWeatherOfRandomCity (request, response) {
const city = CITIES[Math.floor(Math.random() * CITIES.length)]
superagent.get(`wttr.in/${city}`)
.end((err, res) => {
if (err) {
console.log('O snap')
return response.status(500).send('There was an error getting the weather, try looking out the window')
}
const responseText = res.text
response.send(responseText)
console.log('Got the weather')
})
console.log('Fetching the weather, please be patient')
}
function sayHi () {
console.log('Hi')
}
app.listen(3000);
我有這些問題:
superagent.get(
wttr.in/${city} )
向http://wttr.in/sf
發出Web請求時,該請求將被置於任務隊列而不是主要調用堆棧正確嗎?
superagent.get(
wttr.in/${city} ).end(...)
(即被推到任務隊列)直到主調用堆棧為空是否正確才會被調用? 換句話說,在事件循環的每個刻度上,它將從任務隊列中獲取一個項目? localhost:3000/
請求localhost:3000/
一個接一個地進來。 第一個請求將推送堆棧上的sendWeatherOfRandomCity,堆棧上的getWeatherOfRandomCity,然后將web請求superagent.get(
wttr.in/${city} ).end(...)
放在后台隊列中,然后console.log('Fetching the weather, please be patient')
,然后sendWeatherOfRandomCity將從堆棧彈出,最后sayHi()
將被推入堆棧,它將打印“Hi”並彈出堆棧,最后附加到superagent.get(
wttr.in/${city} ).end(...)
結束事件將從任務隊列中調用,因為主調用堆棧將為空。 現在,當第二個請求到來時,它會將所有與第一個請求相同的內容推送到主調用堆棧,但是第一個請求(仍然在任務隊列中)的結束處理程序將首先運行,或者將內容推送到主調用第二個Web請求的堆棧會先運行嗎? 當您發出http請求時,libuv會發現您正在嘗試發出網絡請求。 libuv和node都沒有任何代碼來處理網絡請求涉及的所有這些操作。 而是libuv將請求委托給底層操作系統。
它實際上是內核,它是我們操作系統的重要組成部分,可以完成真正的網絡請求。 Libuv用於發出請求,然后它只是等待操作系統發出一個信號,表明某些響應已經回到請求。 因此,由於Libuv將完成的工作委托給操作系統,操作系統本身決定是否制造新的威脅。 或者只是一般如何處理發出請求的整個過程。 每個不同的操作系統都有不同的方法來處理這個:在linux上它是epoll,在mac os中它被稱為kqueue,在windows中它被稱為GetQueuedCompletionStatusEx。
事件循環中有6個階段,其中一個是i / o輪詢。 每個階段都優先於其他階段。 1號總是定時器。 當時間到了,(或事件完成)定時器的回調將被調用到事件隊列,定時器功能也將移動到事件隊列。 然后事件循環將檢查調用堆棧是否可用。 調用堆棧是函數執行的地方。 你可以一次做一件事,調用堆棧強制我們只能在調用堆棧的頂部有一個函數,這是我們正在做的事情。在JAVASCRIPT RUNTIME中無法同時執行兩件事。
如果調用堆棧為空意味着刪除了main()函數,則事件循環將推送定時器函數調用堆棧並執行您的函數。 在主函數完成之前,所有Async回調都不會運行。
因此,當I / O輪詢階段處理傳入數據和連接時,使用相同的路徑定時器函數如何跟隨,將執行處理提取的函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.