[英]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.