Liu Rui
Liu Rui

Reputation: 23

how to make setTimeout() work as it looks like in for-loop?

how to make setTimeout() work as it looks like in for-loop? like this code

function hello() {
    for (let index = 0; index < 3; index++) {
        setTimeout(function () {
            console.log('What\'s up!')
        }, 3000)
        console.log('Yo')
    }
}

hello()

it logs

Yo
Yo
Yo
What's up!
What's up!
What's up!

How can I make it logs

Yo
What's up(after 3 sec)
Yo
What's up(after 3 sec)
Yo
What's up(after 3 sec)

Thanks for your help.

Upvotes: 2

Views: 86

Answers (6)

Patrick
Patrick

Reputation: 179

If you want to output every 3 seconds another pair of logs, take a look at the following snippet using async/await and promises:

async function hello() {
    for (let index = 0; index < 3; index++) {
        console.log('Yo');
        await new Promise(resolve => {
            setTimeout(function () {
                console.log('What\'s up!');
                resolve();
            }, 3000);
        });
    }
}

hello();

Make sure you check out for example caniuse to check whether the browsers you want to support is supporting async/await and Promise though.

Upvotes: -1

rainh2001
rainh2001

Reputation: 33

You can just make a function which executes itself with setTimeout() but you would have to incorporate a global function as a counter.

let counter = 0;
function hello(n){
    console.log("Yo");
    console.log("What's up?);
    counter++;
    if(counter > n){
        setTimeout(hello, 3000);
    }
}

Upvotes: 0

yqlim
yqlim

Reputation: 7080

You need either Promise or recursion for operations like this.

Promise (without async/await)

async function hello(index = 0) {
    if (index >= 3) return;
    
    index += 1;

    return new Promise(function(resolve){
    
      setTimeout(function(){
        console.log('What\'s up!');
        resolve();
      }, 3000);
      
      console.log('Yo');
      
    }).then(hello.bind(null, index));
}

hello()

Promise (with async/await)

async function hello() {
    for (let index = 0; index < 3; index++) {
        await Promise.all([
          new Promise(function(resolve){
            setTimeout(function(){
              console.log('What\'s up!');
              resolve();
            }, 3000);
          }),
          console.log('Yo')
        ]);
    }
}

hello()

Recursion

function hello(index = 0) {
    if (index >= 3) return;
    
    setTimeout(function(){
      console.log('What\'s up!');
      hello(index);
    }, 3000);
    
    console.log('Yo');
    
    index++;
}

hello()

PS: Codes above assume you use ES2017 and above.

Upvotes: 2

Sweeper
Sweeper

Reputation: 270860

One way to do it is this:

function hello() {
    for (let index = 1; index <= 3; index++) {
        setTimeout(function () {
            console.log('What\'s up!')
        }, 3000 * index)
        setTimeout(function () {
            console.log('Yo')
        }, 3000 * (index - 1))
    }
}
hello()

I basically made use of the for loop index to give each console.log call a different delay. Note how "Yo" is always 3000 ms ahead of "What's up".

Upvotes: 5

Vaibhav Vishal
Vaibhav Vishal

Reputation: 7108

You need something like this:

const times = 3;
var n = 0;

function logYo(){
  console.log('Yo');
  logWhatsUp();
}

function logWhatsUp(){
  setTimeout(() => {
    console.log('Whats Up');
    n++;
    if(n < times)
      logYo();
  }, 3000);
}

logYo();

Upvotes: 0

Kausha Shah
Kausha Shah

Reputation: 309

setTimeout() will not give you desired result even if you put 0 waiting time. Either put both the console.log in setTimeout() or remove setTimeout().

Upvotes: 0

Related Questions