简体   繁体   中英

Concurrency in Express

I would like to set up an API using express that can either multithread or multiprocess requests. For instance, below is an api that sleeps 5 seconds before sending a response. If I call it quickly 3 times, the first response will take 5 seconds, the second will take 10, and the third will take 15, indicating the requests were handled sequentially.

How do I architect an application that can handle the requests concurrently.

const express = require('express')
const app = express()
const port = 4000

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

app.get('/', (req, res) => {
    sleep(5000).then(()=>{
        res.send('Hello World!')
    })

})

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

Edit: request -> response

If I call it quickly 3 times, the first response will take 5 seconds, the second will take 10, and the third will take 15, indicating the requests were handled sequentially.

That's only because your browser is serializing the requests, because they're all requesting the same resource. On the Node.js/Express side, those requests are independent of one another. If they were sent from three separate clients one right after another, they'd each get a response roughly five seconds later (not after 5, 10, and 15 seconds).

For instance, I updated your code to output the date/time of the response:

res.send('Hello World! ' + new Date().toISOString())

...and then opened http://localhost:4000 in three separate browsers as quickly as I could (I don't appear to be all that quick:-)) . The times on the responses were:

16:15:58.819Z
16:16:00.361Z
16:16:01.164Z

As you can see, they aren't five seconds apart.

But if I do that in three windows in the same browser, they get serialized:

16:17:13.933Z
16:17:18.938Z
16:17:23.942Z

If I further update your code so that it's handling three different endpoints:

function handler(req, res) {
    sleep(5000).then(()=>{
        res.send('Hello World! ' + new Date().toISOString())
    })
}

app.get('/a', handler);
app.get('/b', handler);
app.get('/c', handler);

Then even on the same browser, requests for /a , /b , and /c are not serialized.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM