Search code examples
node.jsexpressasync-awaitconcurrency

express concurrent requests with async/await


From what I understand, in express/Node.js, requests are processed concurrently, even when using async/await.

I have made some tests, and I can't understand why the server is waiting for the current request to finish, before handling the next one.

This is my code:

const express = require('express');
const app = express();

// Simulate a long async operation with a non-blocking wait
async function longAsyncOperation() {
  return new Promise(resolve => setTimeout(resolve, 10000));  // 10 seconds delay
}

app.get('*', async function (req, res) {
  console.log("route called");
  try {
    await longAsyncOperation();  // Simulate a long async operation
    res.send("route resolved"); 
  } catch (error) {
    res.send("route rejected");
  }
})

app.listen(8001, () => {
  console.log("Server running on port 8001");
})

Solution

  • Your assertion that "the server is waiting for the current request to finish, before handling the next one" is incorrect.

    First, I took the route add added some debug printing to help us see when the route is resolved or rejected:

    app.get('*', async function (req, res) {
      console.log("route called");
      try {
        await longAsyncOperation();  // Simulate a long async operation
        console.log("route resolved"); // I added this printing
        res.send("route resolved"); 
      } catch (error) {
        console.log("route rejected"); // And this one
        res.send("route rejected");
      }
    });
    

    Then, I created a super-simple shell script that calls the route twice (with curl), but doesn't wait for the response before moving on to the next call:

    ➜  /tmp cat ./curler.sh 
    curl http://localhost:8001 &
    curl http://localhost:8001 &
    

    Then, I invoked this script, and examined the output from the server. As you can see, the second call is handled before the first one resolves:

    ➜  myapp node concurrent.js
    Server running on port 8001
    route called
    route called
    route resolved
    route resolved