node.js 事件循环如何工作,如何处理多个请求?

How that node.js event loop work and how can it handle multiple requests?

提问人:mjsg 提问时间:4/2/2023 最后编辑:jmrkmjsg 更新时间:4/3/2023 访问量:85

问:

我试图在 node.js 中测试一些异步代码。我的理解是,如果正在进行一些异步操作,Node.js 我们将处理新请求。我使用 express 和 axios 编写了一个简单的代码,如下所示。

app.get('/async', (req, res) => {
    axios({
        method: 'get',
        url: 'http://localhost:30000/cpu',
        headers: { 'fibo': '45' }
    })
        .then(ress => {
            console.log(ress)
            res.send('Async success')
        })
        .catch(err => {
            console.log('failed')
            console.log(err)
            res.send('failed')
        })
})
app.get('/', (req, res) => {
    axios({
        method: 'get',
        url: 'http://localhost:30000/'
    }).then(function (response) {
        res.send('Hello World')
    }).catch((err) => {
        res.send('Something wrong happened')
    })

})

向 http://localhost:30000/cpu 发出请求大约需要 15 秒才能完成。因此,当我们向该服务器的 /async 发出请求时,它会反过来向“http://localhost:30000/cpu”发出请求,这需要一些时间。一旦我们得到响应,我的服务器将返回一条消息“异步成功”

我向“/async”发出了请求,并立即向“/”发出了另一个请求。我的期望是,当“/async”仍在进行时,node.js 将同时处理“/”路由并立即发送回响应。但是我观察到“/”仅在“/async”返回后才返回,即“/async”路由阻止了整个服务器。

有人可以解释为什么“/”要等到“/async”完成,我该如何解决这个问题?

JavaScript 节点.js 异步 回调

评论

1赞 jfriend00 4/2/2023
您的路由处理程序不会阻止服务器。但是,您的两个路由都试图联系同一主机,因此它显然不会返回响应,直到完成。如果你选择第二条路线并把它放进去,你应该在路线之前看到它完成。实际上,这两个调用是并行运行的,您将按照它们完成的顺序看到结果。/asynchttp://localhost:30000//cpu/res.send("done")/cpuaxios()
0赞 jfriend00 4/2/2023
仅供参考,stackoverflow 上有数百个关于事件循环如何工作的答案,包括关于并行 Express 事件处理程序的答案。我建议你对这些先前的答案进行一些搜索,以获取有关 nodejs 事件循环的更多信息。你甚至可以搜索我写的答案,至少会找到十几个。
0赞 mjsg 4/2/2023
非常感谢。我不相信我错过了这么愚蠢的一点。再次感谢@jfriend00
0赞 Bergi 4/2/2023
它是什么 ?听起来,如果您从同一个 nodejs 应用程序提供该路由,这将阻止您的服务器http://localhost:30000/cpu

答:

0赞 jfriend00 4/3/2023 #1

您的路由处理程序不会阻止服务器。/async

但是,您的两个路由都试图联系同一主机,因此它显然不会返回响应,直到完成。http://localhost:30000//cpu

如果您采用第二条路线并将其替换为 ,您应该在路线之前看到它完成。/res.send("done")/cpu

实际上,这两个调用是并行运行的,您将按照调用完成的顺序看到结果。因此,哪个请求先完成将与哪个调用先完成有关。axios()axios()axios()

而且,如果是同一个服务器,那么运行这两个请求处理程序的代码也会影响这个等式,因为它们都会争夺同一个 CPU。http://localhost:30000