Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequential function calls in javascript

I want function A to finish execution and only after that function B should start executing. When I call function A and then function B, it seems both are executing simultaneously. And after function B completes, I want to call a third function update_dropdown().

My code looks like this:

function A {
    for (var i = 0; i < 5; i++) {
        var promise = $.get(url+i);
        $.when(promise).then(function () {
            $.post(url);
        });
    }
}
function B {
    var x = $.get(url);
    var promise = $.post(url+x);
    $.when(promise0).then(function () {
        update_dropdown();
    });
}

Please can you tell me how I can make these 3 function calls happen sequentially.

like image 909
Priyanka A Avatar asked May 04 '14 00:05

Priyanka A


People also ask

Does JavaScript execute sequentially?

39.1. 2 JavaScript executes tasks sequentially in a single process. This loop is also called the event loop because events, such as clicking a mouse, add tasks to the queue.

What is sequential execution in JavaScript?

It is basically executing Asynchronous Tasks in series or synchronously. Java is Asynchronous in nature and so is the Node. Node handles multiple requests at the same time by using Event loop and callback functions. There are 2 methods to perform different asynchronous functions synchronously or sequentially: 1.

Can you call a function multiple times in JavaScript?

In order to run a function multiple times after a fixed amount of time, we are using few functions. setInterval() Method: This method calls a function at specified intervals(in ms). This method will call continuously the function until clearInterval() is run, or the window is closed.


2 Answers

OK, it's getting a little bit clearer what you actually want (based on your recent comments to address clarifying questions) though there are still at least two options open.

For an operation like this, you probably want to take advantage of a number of promise features:

  1. jQuery's Ajax calls already return a promise so you can just use those directly
  2. To serialize operations, you can just chain multiple promise operations together
  3. To make async operations serialize properly, you can return a promise from a .then() handler and the master promise will resolve only when all the chained promises have resolved (kind of a built-in $.when() without having to explicitly call $.when()).
  4. You can chain as many operations together as you want and the master promise will tell you when they are all done.
  5. If you return promises from both A() and B(), then the callers of those functions can monitor when they are done with promise methods which then lets you chain A().then(B) to sequence those two.
  6. When you sequence operations with chaining, the prior methods resolve data is passed to the next .then() handler function in the chain as the first argument to the .then() handler function so if you need the prior data for the next operation, it is right there to use.

So, with all those capabilities, it's just a matter of putting the right scaffolding around the code to implement the exact sequencing you want. Here are two different options:


Option 1: If you want to serialize everything in A() so that all 10 requests happen in serial fashion (the next one proceeds only when the prior one is done), then it could look like this:

// serialize all requests
function A() {
    var p = $.get(url).then(function(data) {return $.post(url)});
    for (var i = 1; i < 5; i++) {
        // chain four more pairs of requests onto the original promise
        p = p.then(function() {return $.get(url)})
             .then(function(data) {return $.post(url)});
    }
    // return the promise so callers can monitor when A() is done
    return p;
}


function B() {
    // sequence these three operations one after the other
    return ($.get(url)
       .then(function(data) {return $.post(url + x)})
       .then(update_dropdown)
    );
}

// run them both, one after the other
A().then(B);

Option 2: If you want the 5 pairs of requests in A() to run in parallel, with only the last part of A() waiting until the 5 pairs of requests are done, then it could look like this:

// parallelize pairs of requests
function A() {
    var promises = [];
    for (var i = 0; i < 5; i++) {
        // execute 5 pairs of requests where each pair is serialized in itself
        promises.push($.get(url).then(function(data) {return $.post(url)}));
    }
    // return a promise that resolves only when all the other promises are done
    return $.when.apply($, promises);
}

function B() {
    // sequence these three operations one after the other
    return ($.get(url)
       .then(function(data) {return $.post(url + x)})
       .then(update_dropdown)
    );
}

// run them both, one after the other
A().then(B);

These use the concept that if you return a promise from a .then() handler function, then it will chain multiple async operations together and the master promise is only resolved when all the chained operations are resolved. This is very powerful for sequencing multiple ajax operations and you can even do it for operations in a loop like you have.

like image 140
jfriend00 Avatar answered Oct 10 '22 19:10

jfriend00


Something like this should work

function A {
    var xhr = [];

    for (var i = 0; i < 5; i++) {
        xhr.push( $.get(url) );
    }

    $.when.apply($, xhr).then(B);
}

function B {

    $.get(url).done(function(x) {
        $.post(url + x).done(update_dropdown);
    });

}

Note the use of an array to keep the promises in, then using $.when with apply() to fire a callback when all the ajax requests in the loop has finished.

like image 22
adeneo Avatar answered Oct 10 '22 19:10

adeneo