user1104854
user1104854

Reputation: 2167

check if function has completed its task using javascript/jquery

I'm trying to pause a function until another function has completed its task. Is there anything similar to .ajaxComplete() but for the completion of a function?

This code should simply print out "test" quickly at first and then slow down (decelerate, if you will). As the number in the loop becomes higher, setTimeout becomes longer, hence, it prints "slower" as the loop goes on. Basically, I need the loop to pause until the function has printed.

edit - I updated my code. "test" is only printed once and nothing else happens.

 <html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
</head>
<body>

<input type="button" value="Display alert box" onclick="docWrite()" />
<script>

var b = 0;

function docWrite() {
   document.write("test");
   timeMsg();
}

function timeMsg() {
  b += 250;
  if (b < 5000) { //check the limit
     setTimeout("docWrite()", b - 250); //substract 250 (because we already added 250 before the first print
  }
}
</script>
</body>
</html>

Upvotes: 0

Views: 7645

Answers (3)

Woutifier
Woutifier

Reputation: 313

I think it would be better to let the timeout function start a new timeout function This would solve your problem and get rid of the for loop altogether. Simply call timeMsg() to start the example.

<script>

var b = 0;

function docWrite() {
    $('body').append("test");
    timeMsg();
}

function timeMsg() {
    b += 250;
    if (b < 5000) { //check the limit
        setTimeout(docWrite, b - 250); //substract 250 (because we already added 250 before the first print
    }
}

</script>

Modifying your own script I end up with this:

<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
</head>
<body>

<input type="button" value="Display alert box" onclick="timeMsg()" />
<script>

var b = 0;

function docWrite() {
   $("body").append("test");
   timeMsg();
}

function timeMsg() {
  b += 250;
  if (b < 5000) { //check the limit
     setTimeout(docWrite, b - 250); //substract 250 (because we already added 250 before the first print
  }
}
</script>
</body>
</html>

Upvotes: 3

d_inevitable
d_inevitable

Reputation: 4451

The following function could be used to fullfill your task:

function repeat(action, initial, slowdown, count, callback) {
    function next(time) {
       window.setTimeout(function() {
          if (count--) {
             action();
             next(time+slowdown);
          }
          else
             callback();
       }, time);
    }

    next(initial);
}

You can use it as follows:

repeat(docWrite, 0, 250, 5000/250, function() {
    $("body").append("done"); 
});

function docWrite(){
    $("body").append("test");
}​

Please note that if the action call back (docWrite) performs asynchronous calls, like animations itself for which you want to wait to complete before starting the next timer, then it becomes a little bit more complicated. Let me know if that is the case.

http://jsfiddle.net/JKEpK/4/

Upvotes: 0

Richard Neil Ilagan
Richard Neil Ilagan

Reputation: 14747

You're going to have to add the callback to docWrite(). Have it run something (or the thing you want done after) by passing in a function to it.

function docWrite(callback) {
    document.write('test');
    // something like
    callback();
}

then you can structure it like this:

var b = 0;
function timeMsg(){
    var t = setTimeout(function () {
        docWrite(function () {
            // what to do after this finishes
            if (b > 5000) { return; }
            b += 250;
            timeMsg();
        })
    }, b);
}   

Upvotes: 0

Related Questions