antonjs
antonjs

Reputation: 14318

how to deal with asynchronous function?

I have two asynchronous objects fn1 and fn2 and sometimes I want to run them synchronously.

For simplicity I wrote the code in this way:

var fn1 = function () {
    setTimeout(function () {
        console.log("fn1");
    },200);
};

var fn2 = function () {
    setTimeout(function () {
        console.log("fn2");
    },100);
};

fn1();
fn2(); 

but let's suppose is not possible to modify the fn1 and fn2 object.

What is the best way to run fn2 only when fn1 has finished to be executed?

Upvotes: 3

Views: 1103

Answers (6)

Rob W
Rob W

Reputation: 348982

If you want to execute f1() when f2() has finished, use the method as described and shown below.

Create a poller function, which checks for variable/property changes created by method fn2. Example:

function fn1(){/*...*/}
function fn2(){
    //Lots of code, including:
    window.someDynamicVar = "SPECIAL_token"; //Unique, only defined by this func
}
(function(){//Anonymous wrapper, don't leak variables
    var timer = window.setInterval(function(){
        //check whether an unique environment change has been made by fn2():
        if(window.someDynamicvar == "SPECIAL_token"){
            clearInterval(timer); //Clear the poller
            fn1(); //Call fn1
        }
    }, 200); //Poller interval 200ms
})();

The concept behind this code is that the fn2() function changes variables during/after execution, which can be read. When such a change has been detected, the poller is cleared, and fn1() is executed.

Upvotes: 4

chjj
chjj

Reputation: 14602

fn1 and fn2 are most certainly objects, contrary to what is said below (or above), but that's a different story. The easiest way to do what you want to, it to provide an optional callback parameter.

var fn1 = function (callback) {
    setTimeout(function () {
        console.log("fn1");
        if (callback) callback();
    },200);
};

var fn2 = function (callback) {
    setTimeout(function () {
        console.log("fn2");
        if (callback) callback();
    },100);
};

So instead of:

fn1();
fn2(); 

You would do:

fn1(fn2);

or to be explicit about it:

fn1(function() {
    fn2();
});

Upvotes: 0

hugomg
hugomg

Reputation: 69934

In the general case, there isn't a pretty way. Are you sure you can't change teh functions so they receive continuation functions to call when they are done?

function f1(continuation){
    setTimeout(function(){
        console.log("f1");
        continuation(); //kind of like a return...
    }, 100);
}
function f2(continuation){
    setTimeout(function(){
        console.log("f2");
        continuation();
    }, 100);
}

f1(function(){
    f2( function(){
        console.log("this runs after f2 ends");
    })
})

Upvotes: 0

jtfairbank
jtfairbank

Reputation: 2307

You should use a callback function.

http://recurial.com/programming/understanding-callback-functions-in-javascript/

var fn2 = function (myCallback) {
    setTimeout(function () {
        console.log("fn2");
        myCallback();
    },100); };

Upvotes: 1

user113716
user113716

Reputation: 322472

"...let's suppose is not possible to modify the fn1 and fn2 object."

Without modification, they will behave as asynchronous functions are meant to behave; they will run asynchronously.

If you have foreknowledge of the duration in the first function, you could delay the execution of the second by the same duration.

f1();
setTimeout(f2,200);

Upvotes: 2

Ed Heal
Ed Heal

Reputation: 59997

  1. fn1 and fn2 are not objects
  2. Read up about setTimeout. Get fn1 to call fn2 when it is done

Upvotes: -3

Related Questions