当前位置: 首页 > 知识库问答 >
问题:

Nodejs中的并发

逑和蔼
2023-03-14

我有像下面这样的节点服务器。并且我几乎同时推送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')
    })


共有3个答案

瞿宏儒
2023-03-14

您正在通过在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事件循环。

丁正阳
2023-03-14

“为什么服务器等待第一个请求处理完成,然后将处理第二个请求”?

这对Node.js是不对的。您正在代码中进行同步和异步调用。对sleep()方法的异步调用等待运行12秒。

这并不意味着异步调用会一直等到同步调用结束。这是同步行为。请注意以下示例

asyncFunction1()
asyncFunction2()
asyncFunction3() 

在这里,每当第一个函数开始运行时,node.js释放线程/块,然后第二个函数开始运行,node再次释放线程,因此对第三个函数的调用开始。每个函数在完成时返回响应,而不等待其他函数的返回。

NodeJs是单线程的或具有非阻塞I/O架构。异步特性是它的妙处。

令狐宣
2023-03-14

同意@unclexo-理解什么是阻塞/非阻塞调用,并围绕此优化您的代码。如果您真的想增加并行请求的容量,可以考虑利用集群模块。

https://nodejs.org/api/cluster.html

这将启动子进程并将HTTP请求代理给这些子进程。每个子进程都可以进行阻塞,只要它愿意,并且不影响其他进程(除非它们之间存在某种竞争条件)。

 类似资料:
  • 本文向大家介绍docker中编译nodejs并使用nginx启动,包括了docker中编译nodejs并使用nginx启动的使用技巧和注意事项,需要的朋友参考一下 1.编译Nodejs 要进行Nodejs编译,使用docker就变得非常的方便了。 首先从hub.docker.com下载最新的镜像。https://hub.docker.com/_/node/ 一般的项目都使用的是node6的镜像。

  • 本文向大家介绍深入浅析NodeJs并发异步的回调处理,包括了深入浅析NodeJs并发异步的回调处理的使用技巧和注意事项,需要的朋友参考一下 这里说并发异步,并不准确,应该说连续异步。NodeJs单线程异步的特性,直接导致多个异步同时进行时,无法确定最后的执行结果来回调。举个简单的例子: 连续发起了5次读文件的异步操作,很简单,那么问题来了,我怎么确定所有异步都执行完了呢?因为要在它们都执行完后,才

  • 本文向大家介绍Nodejs中的this详解,包括了Nodejs中的this详解的使用技巧和注意事项,需要的朋友参考一下 以下内容都是关于在nodejs中的this而非javascript中的this,nodejs中的this和在浏览器中javascript中的this是不一样的。 在全局中的this   全局中的this默认是一个空对象。并且在全局中this与global对象没有任何的关系,那么全

  • 您好,我的请求sql中需要发送变量。用于在我的数据库中搜索值 我的问题是语法错误。 谢谢你帮助我。 意外令牌 '%' ?[90mwrapSafe(内部/模块/cjs/loader.js:979: 16)?[39m?[90m模块_compile(内部/模块/cjs/loader.js:1027: 27)?[39m?[90m对象。模块。_extensions... js(内部/模块/cjs/loade

  • tag到底是什么意思?我们为什么需要它?

  • 我正在我的页面welcomeuser中从此路由获取数据 现在我想使用这个锚标记从来到WelcomeUser.ejs页面的value1中获取userid。我该怎么做呢?这是上面WelcomePage.ejs中的一行,我正在其中获取整个数据。