Skip to content

Instantly share code, notes, and snippets.

@bengrunfeld
Last active August 13, 2018 01:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bengrunfeld/81d7d2ee183d41fe0ce8671be9c019ed to your computer and use it in GitHub Desktop.
Save bengrunfeld/81d7d2ee183d41fe0ce8671be9c019ed to your computer and use it in GitHub Desktop.
Concurrent Asynchronous Requests in Node.js (Javascript) using Async/Await

Concurrent Requests in Node.js (Javascript) using Async/Await

To make concurrent asynchronous requests in NodeJS (Javascript), we can take advantage of the setTimeout function and use it together with async/await, plus trusty old count.

What we are aiming for here is that 3 requests get sent asynchronously, but the promise they're contained in only resolves when ALL 3 have returned. If it takes too long, we want to reject the promise, since the data has likely become stale.

Originally I tried using Promise.all(), but ran into problems with it. The following implementation worked MUCH better for me.

const makeRequest = () => {
  const p = new Promise((resolve, reject) => {
    setTimeout(() => resolve('hello'), 1000)    // Just use a timer to mock a real HTTP request
  })

  p.catch(err => console.log(err))
  return p
}

const makeConcurrentRequests = endpoints => {
  const p = new Promise((resolve, reject) => {

    let results = []
    let count = 0

    setTimeout(async() => {
      results[0] = await makeRequest(endpoints[0])
      count++
      console.log('Result 1:', results[0])
    })

    setTimeout(async() => {
      results[1] = await makeRequest(endpoints[1])
      count++
      console.log('Result 2:', results[1])
    })

    setTimeout(async() => {
      results[2] = await makeRequest(endpoints[2])
      count++
      console.log('Result 3:', results[2])
    })

    console.log('This should execute fist...')


    /*
      Now we'll use a timer to ensure that all our requests 
      have returned before a threshold. E.g. in trading, if
      it's taken more than x milliseconds for data to return, 
      the data is considered stale and useless, so we may as
      well ignore it and move on.
    */
    
    const intervalCount = 0

    const int = setInterval(() => {
      if (count === 3) {
        console.log(`makeConcurrentRequests finished after ${intervalCount * 100} ms`)
        resolve(allDepths)
        clearInterval(int)
      }

      if (intervalCount > 20) {
        reject(`getAllDepthsAsync timed out after 2000 ms...`)
        clearInterval(int)
      }
      
      intervalCount++
    }, 100)
  })
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment