Jquery post call function n times, but wait for each to complete before calling the next

I have a list of things that I post to PHP one at a time through $.post

. I want to wait for each one to complete before calling the next one. I want to do this when JS is not looping with PHP as I want the return value to be displayed by each one.

var list = ["a", "b", "c"];
for (i = 0; i < list.length; i++) {
  $.post(con, {
    callScript: list[i],
  }, function(data, status) {
    //Do stuff here with the data on success

  });
}

      

I have looked $.when

but just can't figure out how to use it. In any case, it is assumed that there is a certain number of functions, and not the same function n times. I also know that async false is not allowed.

Is there a way to run this?

+3


source to share


3 answers


Recursion is your good friend here. You can create a function that calls itself for each element, calling the next one after the current async operation completes. The recursion stops when we run out of elements.

function postInOrder(list, index = 0) {
  if (index < list.length) {
    $.post(con, {
      callScript: list[index],
    }, function success(data, status) {
      // do stuff here with the data on success
      // ...
      postInOrder(list, index + 1); // <-- run next script on completion
    });
  }
}

postInOrder(["a", "b", "c"])

      

Here's an example with a fake method post

:



function postInOrder(list, index = 0) {
  if (index < list.length) {
    console.log(`Start: ${list[index]}`)
    post(function success() {
      console.log(`Finish: ${list[index]}`)
      postInOrder(list, index + 1); // <-- run next script on completion
    });
  }
}

postInOrder(["a", "b", "c"])

function post(cb) { setTimeout(cb, 1000); }
      

Run codeHide result


+3


source


You can also shrink it down to the Promise Queue:

list.reduce(function(prom,listEl){
  return prom.then(function(){
   return new Promise(function(next){
    $.post(con, {
      callScript: listEl,
    }, function(data, status) {
      //Do stuff here with the data on success
      next();
    });
  });
 });
},Promise.resolve());

      



(I think wrapping in a promise is not necessary, can someone who avoids jquerys syntax edit freely;))

+3


source


There is a very widely used library called "async" that makes this thing very simple. Below are the docs for the async series that you probably want to do here.

Here's an example from the docs:

async.series([
    function(callback) {
        // do some stuff ...
        callback(null, 'one');
    },
    function(callback) {
        // do some more stuff ...
        callback(null, 'two');
    }
],
// optional callback
function(err, results) {
    // results is now equal to ['one', 'two']
});

      

The sample callback passes an error as the first parameter if something went wrong, otherwise pass null as the first parameter and then the actual return value as the second parameter. This pattern is used in all asynchronous JavaScript on the server and in the browser.

This final function is what is executed after the end of the series.

You may also run into this, knowing that variables can be functions in JavaScript and build your queue like this:

var processMe = [];

processMe.push(callScript('two'));
processMe.push(callScript('four'));
processMe.push(callScript('six'));

async.series([ processMe ],
function(err, results) {
    // results is now equal to ['two', 'four', 'six']
});

function callScript(value, callback) {
  // do something here
  callback(null, value);
}

      

You can also use waterfall if you need to pass results from one step to another.

If it really is the same code multiple times, use the times operator to simply repeat the same function N times:

// Pretend this is some complicated async factory
var createUser = function(id, callback) {
    callback(null, {
        id: 'user' + id
    });
};

// generate 5 users
async.times(5, function(n, next) {
    createUser(n, function(err, user) {
        next(err, user);
    });
}, function(err, users) {
    // we should now have 5 users
});

      

0


source







All Articles