[jquery] Execute jQuery function after another function completes

I want to execute a custom jQuery function after another custom function completes
The first function is used for creating a "typewriting" effect

function Typer()
{
    var srcText = 'EXAMPLE ';
    var i = 0;
    var result = srcText[i];
    setInterval(function() {
        if(i == srcText.length) {
            clearInterval(this);
            return;
        };
        i++;
        result += srcText[i].replace("\n", "<br />");
        $("#message").html( result);
    },
    100);

}

and the second function plays a sound

function playBGM()
{
    document.getElementById('bgm').play();
}

I am calling the functions one after the another like

Typer();
playBGM();

But the sound starts playing as the text is getting typed. I want to play the sound only AFTER the typewriting has finished.

Here is what I have tried: http://jsfiddle.net/GkUEN/5/

How can I fix this?

This question is related to jquery function

The answer is


You can use below code

$.when( Typer() ).done(function() {
       playBGM();
});

Deferred promises are a nice way to chain together function execution neatly and easily. Whether AJAX or normal functions, they offer greater flexibility than callbacks, and I've found easier to grasp.

function Typer()
{
var dfd = $.Deferred();
    var srcText = 'EXAMPLE ';
    var i = 0;
    var result = srcText[i];

UPDATE :

////////////////////////////////

  var timer=    setInterval(function() {
                    if(i == srcText.length) {

    // clearInterval(this);


       clearInterval(timer);

////////////////////////////////


   dfd.resolve();
                        };
                        i++;
                        result += srcText[i].replace("\n", "<br />");
                        $("#message").html( result);
                },
                100);
              return dfd.promise();
            }

I've modified the play function so it returns a promise when the audio finishes playing, which might be useful to some. The third function fires when sound finishes playing.

   function playBGM()
    {
      var playsound = $.Deferred();
      $('#bgm')[0].play();
      $("#bgm").on("ended", function() {
         playsound.resolve();
      });
        return playsound.promise();
    }


    function thirdFunction() {
        alert('third function');
    }

Now call the whole thing with the following: (be sure to use Jquery 1.9.1 or above as I found that 1.7.2 executes all the functions at once, rather than waiting for each to resolve.)

Typer().then(playBGM).then(thirdFunction);  

Before today, I had no luck using deferred promises in this way, and finally have grasped it. Precisely timed, chained interface events occurring exactly when we want them to, including async events, has never been easy. For me at least, I now have it under control thanks largely to others asking questions here.


You could also use custom events:

function Typer() {
    // Some stuff

    $(anyDomElement).trigger("myCustomEvent");
}


$(anyDomElement).on("myCustomEvent", function() {
    // Some other stuff
});