Sequential JQuery AJAX using recursive creation of Promises

So I’m in JQuery-land.

I’ve got an array of 100K ID’s on the client-side, and I want to POST them to a back-end API which will respond with JSON, in batches of 100 at a time. So that’s 1000 individual posts.

I don’t want to just loop and create 1000 `$.post`s, because I don’t want the browser trying to do 1000 requests “at once.” So some kind of promise chaining is called for.

But I don’t really even want to create all 1000 promises at once, that’s a lot of things in memory, doing who knows what.  I want to go in sequence through each batch, waiting for each batch to be done, and creating the next promise/AJAX request in the chain only after the first one finishes.

Here’s one way to do it, using a recursive function to create the AJAX promises.

var bigArrayOfIds; // assume exists
var bigArrayLength = bigArrayOfIds.length;
var batchSize = 100;

function batchPromiseRecursive() {
  // note splice is destructive, removing the first batch off
  // the array
  var batch = bigArrayOfIds.splice(0, batchSize);

  if (batch.length == 0) {
    return $.Deferred().resolve().promise();

  return $.post('/endpoint/post', {ids: batch})
    .done(function(serverData) {
      // Do something after each batch finishes. 
      // Update a progress bar is probably a good idea. 
    .fail(function(e) {
      // if a batch fails, say server returns 500,
      // do something here. 
    .then(function() {
      return batchPromiseRecursive();

batchPromiseRecursive().then(function() {
  // something to do when it's all over. 

In this version, if one batch fails, execution stops entirely. In order to record the failure but keep going with the next batches, I think you’d just have to take the then inside the batchPromiseRecursive function, and give it a second error argument, that would convert the failed promise to a succesful one. i haven’t gotten that far. I think JQuery (ES6?) promise API is a bit more confusing/less concise than it could be for converting a failed state a resolved one in your promise chain.

Or maybe I just don’t understand how to use it effectively/idiomatically, I’m fairly new to this stuff. Other ways to improve this code?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s