Introduction

In this article, we shall learn how to make a concurrent HTTP request. Let’s get started!

The async-mutex library

JavaScript is single-threaded, meaning everything happens in a single thread with all asynchronous operations pushed to an event queue. We shall use async-mutex library to mimic concurrency in other languages like Java.

All code for this article can be found under this repository:

// client.js
const { Semaphore } = require('async-mutex')

const users = [
  {
    name: 'Haruki Narukami',
    age: 45,
    village: 'Hidden Leaf',
  },
  {
    name: 'Haruki Narukami',
    age: 45,
    village: 'Hidden Leaf',
  },
  {
    name: 'Haruki Narukami',
    age: 45,
    village: 'Hidden Leaf',
  },
  {
    name: 'Haruki Narukami',
    age: 45,
    village: 'Hidden Leaf',
  },
  {
    name: 'Haruki Narukami',
    age: 45,
    village: 'Hidden Leaf',
  },
  {
    name: 'Haruki Narukami',
    age: 45,
    village: 'Hidden Leaf',
  },
  {
    name: 'Haruki Narukami',
    age: 45,
   village: 'Hidden Leaf',
  },
  {
    name: 'Haruki Narukami',
    age: 45,
    village: 'Hidden Leaf',
  },
  {
    name: 'Haruki Narukami',
    age: 45,
    village: 'Hidden Leaf',
  },
  {
    name: 'Haruki Narukami',
    age: 45,
    village: 'Hidden Leaf',
 }
]

const NUMBER_OF_FAKE_THREADS = 4
const semaphore = new Semaphore(NUMBER_OF_FAKE_THREADS)

const main = async() => {
  users.foreach(async () => {
    const [value, release] = semaphore.acquire()
    try {
      const res = await axios.post(user, headers)
      return res
    } catch(error) {
      release()
    } finally() {
      release()
    }
  })
}
  1. Create a small backend to handle the incoming requests:
// server.js
const express = require('express')
const app = express()
const port = process.env.PORT || 3000

app.get('/user', (req, res) => {
  const user = req.body!.user
  // store to an in-memory DB:
  try {
    const result = await DB.save(user)
    res.send({success: ok, message: result})
  } catch(e) {
    res.send({msg: 'failed'})
  }
})

Discussion

In the above example, we have an array of 10 users, and we want to upload every single user to our custom backend. We use an async-mutex to send each request to the HTTP serve by requiring the Sephamore class and creating an instance, passing in the number of “threads” to use for the requests.