Wanna see something cool? Check out Angular Spotify 🎧

Limit the number of simultaneous ajax requests

Recently, we changed to use HTTP2 and our DevOps told me that there are some limitations of the current platform. In some specific area, there could be a few hundreds of request will be fired in parallel and could cause the system freeze. He wanted to limit the number of simultaneous requests to 100, and queue up the rest. I came up with a simple function for doing so.

var lazyLoadAjaxManager = (function() {
  const MAX_PARALLEL_CALL = 100
  var queue = [] //to store the URL
  var activeCall = 0

  function queueRequest(url) {
    queue.push(url)
    checkQueue()
  }

  function onPromiseCompleteOrFailure() {
    activeCall--
    checkQueue()
  }

  function checkQueue() {
    if (queue.length && activeCall <= MAX_PARALLEL_CALL) {
      let url = queue.shift()
      if (!url) {
        return
      }

      activeCall++

      fetch(url)
        .then(res => res.json())
        .then(response => {
          onPromiseCompleteOrFailure()
          //TODO Write your custom logic here
          console.log('Success:', JSON.stringify(response))
        })
        .catch(error => {
          onPromiseCompleteOrFailure()
          console.error('Error:', error)
        })
    }
  }

  return {
    addRequest: queueRequest,
  }
})()

//To use -> call addRequest(url). Usually for a large number of request, we will do it inside a loop. E.g
// for (const userId of userIds) {
//     lazyLoadAjaxManager.addRequest(`https://example.com/user/${userId})
// }

lazyLoadAjaxManager.addRequest('https://example.com/request1')
lazyLoadAjaxManager.addRequest('https://example.com/request2')
lazyLoadAjaxManager.addRequest('https://example.com/request3')
lazyLoadAjaxManager.addRequest('https://example.com/request4')

Basically, I first pushed all request url to a queue with a function called addRequest and call checkQueue. checkQueue checks to see if there are items in the queue and if the number of active requests is less than MAX_PARALLEL_CALL. If these conditions are met, it pops a request from the queue and turns it into a real AJAX request. Then it attaches a done handler to the request that decreases the active request count and calls checkQueue.

Why I am still using var? Because it is the pure JS file will be served directly with no Babel or TypeScript compiled. So for safe, I am still using the old syntax.

Published 21 Jun 2019

Read more

 — Angular formArray/formGroup - Validate at least one checkbox was selected
 — Restrict null and undefined via Non-Nullable-Types in TypeScript
 — Error handling in JavaScript. Synchronous vs asynchronous code
 — TypeScript - Declare a function callback type
 — Angular [(ngModel)] and debounce

Follow @trungvose on Twitter for more!