0

What I have attempted to do is write a function such as:

function delay(delay){
    var date = new Date();
    var startTime = date.getTime();


    var currDate=new Date();
    var current=currDate.getTime();

    while (current<=startTime+delay){
        currDate=new Date();
        current=currDate.getTime();
    }
}

This code seems to work perfectly when doing something such

console.log("1");
delay(500);
console.log("2");

When doing something like that, it will print out to the console 1, then wait half a second, then print out 2. The issue is that I don't want to console.log, I want to document.getElementById("id").innerHTML+="a";. When trying that surrounding the delay function, the page waits for all of the delay to finish before loading any of the a's.

My question is the following:

Is there a good way to either write such a function, or is there already a function, that can allow all previous code to run, cause a specified delay, and then run the code after it. I have tried using setTimeout, but the issue is that running something like this:

console.log("1");
setTimeout(function(){
    console.log("2");
}, 2000);
console.log("3");

results in it printing 1, then printing 3, then waiting 2 seconds and printing 2, rather than doing 1, wait 2 secs, print 2, print 3

Clarification: The way I am trying to implement this is:

for (i=0;i<10;i++){
    document.getElementById("text")+="a";
    delay(500);    
}

What this code is supposed to do is print one letter at a time to the screen, with half a second in between each letter print

Benya12
  • 33
  • 5

2 Answers2

0

setTimeout is the correct approach.

You would want

console.log("1");
setTimeout(function(){
    console.log("2");
    console.log("3");
}, 2000);

which will log "1", wait 2s, then log "2" and "3" in that order.

The reason why your example doesn't work is because setTimeout is asynchronous. That means that the function passed to setTimeout is scheduled for 2s from the time setTimeout is called but the program will continue executing any following lines. Anything you want to wait until after the delay should be in the block inside setTimeout.

If you want further delays after your delay, you may call setTimeout from within the callback function.

For example:

console.log("1");
setTimeout(function(){
    console.log("2");
    setTimeout(function() {
        console.log("3");
    }, 1000);
}, 2000);

Which will log "1", wait 2s, log "2", wait 1s, then log "3".

--

Loop with delay:

while () { console.log("1"); (2000); console.log("2"); console.log("3"); }

becomes

var loop = function() {
  console.log("1");
  setTimeout(function() {
    console.log("2");
    console.log("3");
    if (<condition>) {
      loop();
    }
  });
};

Note that for large numbers of iterations, you may exceed available stack. In this case, you may resort to some workaround like setTimeout(loop, 0);

arcyqwerty
  • 8,893
  • 2
  • 40
  • 77
  • The issue with this is that I want to run the code in a loop and I want a particular action to take place, then a wait, and then the for loop should continue – Benya12 May 05 '16 at 04:35
  • I have updated my question to include what I want my code to do – Benya12 May 05 '16 at 04:38
  • In other words, how do I do synchronous things in an language and environment designed to be asynchronous (asynchronous = not wait for things)? The problem is, if you tie up the CPU with a tight while loop, as you did in your question, the response of the UI will suffer. – Greg Bell May 05 '16 at 04:39
  • If you want to continue looping, see updated answer – arcyqwerty May 05 '16 at 14:21
0

you can achieve something similar using callbacks:

function execute_after_delay( cb, msg, delay ){
   setTimeout(function(){
       console.log("2");
       cb(msg);
   }, delay);
}
console.log("1");
execute_after_delay(console.log, 3, 2000);
Tudor Constantin
  • 24,065
  • 7
  • 44
  • 66