2

Here is what I want to do:

setSource is a function which executes about 3 seconds.

 editor.setSource();

 setTimeout(function () {
      //do something, some commands
 }, 3000);

I want the //do something, some commands part to be executed AFTER the last line of setSource() is executed. Now I'm doing it with setTimeout, but I think it's not very good solution, because sometimes setSource() will take maybe 5 seconds to execute. How to do this?

petko_stankoski
  • 10,459
  • 41
  • 127
  • 231

3 Answers3

7

Have setSource take a callback argument:

editor.setSource = function(callback) {
    // do editor things
    callback();
}

Then pass the next block of code to be executed as a callback:

editor.setSource(function() {
    // do some other things
});

If you have access to jQuery's deferred objects, you can make use of them here:

  1. Make a new deferred object.
  2. Start the timeout to do your long task.
  3. Return the deferred object.
  4. In the timeout, once the task is complete, call deferred.resolve.

 

editor = {
    setSource: function() {
        var deferred = $.Deferred();

        console.log("Beginning editor.setSource...");

        setTimeout(function() {
            // This function took a while to occur
            deferred.resolve();
        }, 3000);

        return deferred;
    }
}

$.when(editor.setSource()).then(function() {
    console.log("Editor is done!");
});

If you're doing AJAX or animation or another jQuery task that uses deferred objects already, you can just return its result value instead of making your own deferred object:

editor = {
    setSource: function() {
        return $.get({
            url: "myurl.com/mypage",
            data: $("#myform").serialize()
        });
    }
}

$.when(editor.setSource()).then(function() {
    console.log("Editor is done!");
});

Make sure to look up how you can either resolve or reject deferred objects, and how to handle those.

Waleed Khan
  • 11,426
  • 6
  • 39
  • 70
3

This answer uses promises, a JavaScript feature of the ECMAScript 6 standard. If your target platform does not support promises, polyfill it with PromiseJs.

In newer browser versions you can use ES6 promises. editor.setSource() wraps its execution into a Promise and returns it, so it can be continued with other functions.

editor.setSource = function(){
    return new Promise(function(fulfill, reject){
        //do your work
        fulfill(resultValue);
    });
};

To continue it with another function simply use the then method on the promise.

var promise = editor.setSource();
promise.then(function(result){
    //do something more
});
Domysee
  • 12,718
  • 10
  • 53
  • 84
0

I was also looking for solution where I want to execute my second function only after previous function gets executed completely, I tried callback function but still not getting the solution, finally I find the very easiest way to resolve this issue by using simple $.ajax({ }); method code which works for me :).

for example,

$.ajax({
  url: function1(),
  success: function(){
    //function 2 code here or just call function2() here
  }
}); 

that's all, in this code url parameter will call first function and only on the success of its execution function 2 will be called.

Dan Lowe
  • 51,713
  • 20
  • 123
  • 112