嵌套的for循环,每个循环都有延迟

4

一个简单的嵌套for循环示例:

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("---");
  }
}

延迟嵌套的for循环:

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);
}

现在我的问题是

如何分别控制每个循环的延迟时间。

当前输出(忽略“---”):

i、j、delay、i、j、delay、...

期望输出(忽略“---”):

i、delay、j、delay、i、delay、j、delay、...

我尝试了以下方法(但它返回完全错误的输出):

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);
}


你可能想要使用 setTimeout(…, 1000*(i*3+j))。然而,我建议在 async function 中使用带有 Promise 的 await delay(1000),这样可以避免任何复杂的计算。参考链接:https://dev59.com/DHA65IYBdhLWcg3w4C0L#44476626 - Bergi
3个回答

3
你可以使用Promiseasync/await来处理顺序调用。

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()


参考资料:


3

setTimeout的作用是在其自身的领域中工作,不受for循环或其他任何代码的限制。它实际上并不会完全"阻塞"当前代码,在for循环中,你只是设置了一堆间隔,这些间隔一个接一个地非常快地执行(因为for循环不会被timeout停止或延迟),稍后每个间隔都会以某种未知的顺序执行,当每个间隔的时间到达时,它不会被阻塞或者依赖于任何其他间隔的运行时间。

如果你想保持相对相同的格式,但又需要延迟阻塞,可以使用await和promise以及async函数。

(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));
}



2
您可以尝试使用async/await进行异步处理:

function sleep(ms) {
  return new Promise(resolve => {
    setTimeout(resolve, ms);
  });
}

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

async function taski(i) {
  await sleep(1000 * i);
  console.log("i is: " + i);
}
async function taskj(j) {
  await sleep(1000 * j);
  console.log("j is: " + j);
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接