2
votes

I have node server like below. And i push 2 request that almost simultaneously(with the same url = "localhost:8080/"). And my question is: "Why the server wait for 1st request handle done, then 2st request will be handle"?

  • Output in console of my test:
Home..
Home.. 

(Notes: 2nd line will be display after 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
How did you push those 2 request? Cannot reproduce your result, the 2 Home... appears without sleeping for me, I am using 2 bash instance with curlWilliam Chong

3 Answers

1
votes

Agreed with @unclexo - understand what the blocking/non-blocking calls are and optimize your code around that. If you really want to add capacity for parallel requests, you could consider leveraging the cluster module.

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

This will kick off children processes and proxy the HTTP requests to those children. Each child can block as long as it wants and not affect the other processes (unless there is some race condition between them).

0
votes

"Why the server wait for 1st request handle done, then 2st request will be handle"?

This is not right for Node.Js. You are making a synchronous and asynchronous call in your code. The asynchronous call to the sleep() method waits for 12 seconds to be run.

Now this does not mean the asynchronous call waits until the synchronous call finishes. This is synchronous behavior. Note the following examples

asyncFunction1()
asyncFunction2()
asyncFunction3() 

Here whenever the 1st function starts running, then node.js releases thread/block, then 2nd function starts running, again node releases thread, so the call to 3rd function starts. Each function returns response whenever it finishes and does not wait for other's return.

NodeJs is single-threaded or has non-blocking i/o architecture. Asynchronous feature is its beauty.

0
votes

You are blocking the other request by calling await at app.get('/'.... If you want the sleep method to run asynchronously between requests, wrap it in a new async function. The code will be like this:

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));
}

This way, if you send a request and then send another request, the second request's print() function will be executed without waiting for 12 seconds from the first request. Therefore, there will be 2 Home ... printed at around 12 seconds after the request sent. To have more understanding about this, you should learn about NodeJS Event Loop.