我有像下面这样的节点服务器。并且我几乎同时推送2个请求(使用相同的url=“localhost:8080/”)。我的问题是:“为什么服务器等待第一个请求处理完成,然后将处理第二个请求”?
Home.. Home..
(注意:第2行将在12second后显示)-server.js:
var express = require('express') var app = express() app.use(express.json()) app.get('/', async(request, response) => { try { console.log('Home ...') await sleep(12000) response.send('End') } catch (error) { response.end('Error') } }) function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } var server = app.listen(8080, '127.0.0.1', async () => { var host = server.address().address var port = server.address().port console.log('==================== START SERVER ===================') console.log('* Running on http://%s:%s (Press CTRL+C to quit)', host, port) console.log('* Create time of ' + new Date() + '\n') })
同意@unclexo-理解什么是阻塞/非阻塞调用,并围绕此优化您的代码。如果您真的想增加并行请求的容量,可以考虑利用集群模块。
https://nodejs.org/api/cluster.html
这将启动子进程并将HTTP请求代理给这些子进程。每个子进程都可以进行阻塞,只要它愿意,并且不影响其他进程(除非它们之间存在某种竞争条件)。
“为什么服务器等待第一个请求处理完成,然后将处理第二个请求”?
这对Node.js是不对的。您正在代码中进行同步和异步调用。对sleep()
方法的异步调用等待运行12
秒。
这并不意味着异步调用会一直等到同步调用结束。这是同步行为。请注意以下示例
asyncFunction1()
asyncFunction2()
asyncFunction3()
在这里,每当第一个函数开始运行时,node.js释放线程/块,然后第二个函数开始运行,node再次释放线程,因此对第三个函数的调用开始。每个函数在完成时返回响应,而不等待其他函数的返回。
NodeJs是单线程的或具有非阻塞I/O架构。异步特性是它的妙处。
您正在通过在app.get(“/”...
处调用await
来阻止另一个请求。如果希望sleep方法在请求之间异步运行,请将其包装在一个新的异步函数中。代码如下所示:
app.get('/', (request, response) => {
try {
print()
response.send('End')
} catch (error) {
response.end('Error')
}
})
async function print() {
await sleep(12000)
console.log('Home ...')
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
这样,如果您发送一个请求,然后再发送另一个请求,第二个请求的print()函数将被执行,而不需要从第一个请求开始等待12秒。因此,在请求发送后的大约12秒内,将打印出2个home...
。要对此有更多的理解,您应该了解NodeJS事件循环。