Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested for loop,delay on each loop individually

An example of simple nested for loop:

for (let i=0; i<=2; i++) {
  for (let j=0; j<=1; j++){
    console.log("i is: " + i);
    console.log("j is: " + j);
    console.log("---");
  }
}

Nested for loop with delay:

for (let i=0; i<=2; i++) {
  for (let j=0; j<=1; j++){
    task(i,j);
  }
} 

function task(i,j) { 
  setTimeout(function() { 
    console.log("i is: " + i);
    console.log("j is: " + j);
    console.log("---")
  }, 1000 * i);
}

NOW MY QUESTION IS

How can I delay each loop seperately.

Current output (ignore the "---"):

i, j, delay, i, j, delay, ...

Desired output (ignore the "---"):

i, delay, j, delay, i, delay, j, delay ...

I tried things like below (but its returning a complete wrong output)

for (let i=0; i<=2; i++) {
  for (let j=0; j<=1; j++){
    taski(i);
    taskj(j)
  }
} 

function taski(i) { 
  setTimeout(function() { 
    console.log("i is: " + i);
  }, 1000 * i);
}
function taskj(j){
  setTimeout(function() { 
    console.log("j is: " + j);
    }, 1000 * j);
}
like image 749
Evik Ghazarian Avatar asked Jan 25 '23 19:01

Evik Ghazarian


2 Answers

You could use Promise and async/await to handle sequential call

function taski(i) {
  return new Promise(function (resolve) {
    setTimeout(function () {
      console.log("i is: " + i)
      resolve()
    }, 1000 * i)
  })
}
function taskj(j) {
  return new Promise(function (resolve) {
    setTimeout(function () {
      console.log("j is: " + j)
      resolve()
    }, 1000 * j)
  })
}

async function execute() {
  for (let i = 0; i <= 2; i++) {
    for (let j = 0; j <= 1; j++) {
      await taski(i)
      console.log("delay")
      await taskj(j)
      console.log("delay")
    }
  }
}

execute()

Reference:

  • async function
  • Promise
like image 83
hgb123 Avatar answered Jan 27 '23 07:01

hgb123


Ok the thing is setTimeout works in it's own world that isn't limited by the for loops, or any other code for that matter, it doesn't actually "block" the current code at all, in the for loop you are just setting up a bunch of intervals, really fast one after the other (since the for loop doesn't stop or get delayed by the timeouts), which later execute in some unknown order when the time for each one individually runs out, which is not blocked or dependant on any of the other timeouts

If you want to keep relatively the same format you have now, but with delay blocking you can use await and promises and async functions

(async () => 
for (let i=0; i<=2; i++) {
  for (let j=0; j<=1; j++){
    await taski(i);
    await taskj(j)
  }
} 
)()
function taski(i) { 
  return new Promise((rs) => setTimeout(function() { 
    res(console.log("i is: " + i));
  }, 1000 * i));
}
function taskj(j){
    return new Promise((rs) => setTimeout(function() { 
    res(console.log("j is: " + j)
    }, 1000 * j));
}


like image 23
B''H Bi'ezras -- Boruch Hashem Avatar answered Jan 27 '23 07:01

B''H Bi'ezras -- Boruch Hashem