递归setTimeout中的递归setTimeout

问题描述

我创建动画,它们是有时间限制的。一个跟随另一个。我需要一个完全不同的动画才能开始制作一个动画,这与第一个动画无关,动画的第一个周期要等到第二个周期结束,然后才能继续工作。

我决定通过一组递归计时器来实现此目的,但是问题是,第一个动画周期拒绝了第二个动画周期,并阻止了第二个周期正确完成。也就是说,它们不同步。如何让第一个周期等待第二个周期结束?

var func = function(i){

return function(){
    if (i >= 5) return;
    console.log("turn no. " + i);

    // running second recursion 
    var func2 = function(i_){

        return function(){
            if (i_ >= 75) return;
            console.log("turn no2. " + i_);
    
            if(i_ >= 75) {
                console.log('2 Player won');
            } else {
                setTimeout(func2(++i),2000); 
            }
    
        }   
    }
    setTimeout(func2(0),2000); 
    // end running second recursion

    if(i >= 5) {
        console.log('1 Player won');
    } else {
        setTimeout(func(++i),100); 
        }

    }   
}

setTimeout(func(0),100); 

非常感谢)
所需的最终输出
转号。 0
转2号。 0
转2号。 1
转2号。 2
转2号。 3
转2号。 4
转2号。 5
2名玩家赢得了
转号。 1
转2号。 0
转2号。 1
转2号。 2
转2号。 3
转2号。 4
转2号。 5
2名玩家赢得了
转号。 2
转2号。 0
转2号。 1
转2号。 2
转2号。 3
转2号。 4
转2号。 5
2名玩家赢得了
转号。 3
转2号。 0
转2号。 1
转2号。 2
转2号。 3
转2号。 4
转2号。 5
2名玩家赢得了
转号。 4
转2号。 0
转2号。 1
转2号。 2
转2号。 3
转2号。 4
转2号。 5
2名玩家赢得了
转号。 5
转2号。 0
转2号。 1
转2号。 2
转2号。 3
转2号。 4
转2号。 5
2名玩家赢得了
1名玩家赢得了
ps。我想要的是一般有可能吗?)))
p.s.s我只需要以某种方式制作两个具有时间依赖性的相关动画

解决方法

这是您的预期行为吗?我已更正了您实施的游戏逻辑,并在所有位置放置了5次计数器,而不是75次,以简化操作并加快测试速度。还修改了从超时中调用函数的方式-添加了必须在毫秒数后传递给函数的参数。

var func = function(i){
  console.log("turn no. " + i);
  var func2 = function(i_){
    console.log("turn no2. " + i_);
    if(i_ >= 5) {
      // If reach limit - end second recursion
      console.log('2 Player won');
      return;
    } else {
      // Launch new cycle in second recursion
      setTimeout(func2,500,++i_);
    }
  }
  // Run second recursion
  setTimeout(func2,0);
  if(i >= 5) {
    // If reach limit - end first recursion
    console.log('1 Player won');
    return;
  } else {
    // Launch new cycle in first recursion
    setTimeout(func,3000,++i); 
  } 
}

// When setting timeout function you can pass arguments
// to your function after milliseconds number,// 3rd+ parameter,like this
//
// Run first recursion
setTimeout(func,0);

无论如何,setTimeout最终将并行运行,因此,如果您要创建异步代码,则一个函数必须等待另一个函数-最好使用async / await和promises,因为它们是专门为这个。查看下面的代码并阅读评论

// Set pause function
const timeout = (ms) => new Promise(resolve => setTimeout(resolve,ms));
// Set main async function
const main = async () => {
  // Settings
  let no1t = 5;
  let no2t = 5;
  // No1 function
  let i1 = 0;
  const no1 = () => {
    return new Promise(async (resolve,reject) => {
      console.log(`No1: ${i1}`);
      // Run no 2 and wait untill it will be resolved
      await no2();
      // Print that cycle completed
      console.log(`No1: ${i1} completed!`);
      // Wait a sec
      await timeout(1000);
      // If cycles not finished yet,run recursion
      if(i1 < no1t) {
        i1++;
        i2 = 0;
        await no1();
      }
      // Resolve promise after all
      resolve();
    });
  };
  
  // No2 function
  let i2 = 0;
  const no2 = () => {
    return new Promise(async (resolve,reject) => {
      console.log(`-No2: ${i2}`);
      // Wait
      await timeout(500);
      // If cycles not finished yet,run recursion
      if(i2 < no2t) {
        i2++;
        await no2();
      } else {
        // Print that cycle completed
        console.log(`-No2: completed!`);
      }
      // Resolve promise after all
      resolve();
    });
  }
  // Run no1 and wait untill it finishes
  await no1();
  // Log completed
  console.log(`Everything completed`);
}
// Run program
main();