首页 > 解决方案 > 递归 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 玩家在第 5
回合获胜。1
转2号。0
转2号。1
转2号。2
转2号。3
转2号。4
转2号。5
2 玩家在第 5
回合获胜。2
转2号。0
转2号。1
转2号。2
转2号。3
转2号。4
转2号。5
2 玩家在第 5
回合获胜。3
转2号。0
转2号。1
转2号。2
转2号。3
转2号。4
转2号。5
2 玩家在第 2
回合获胜。4
转2号。0
转2号。1
转2号。2
转2号。3
转2号。4
转2号。5
2 玩家在第 5
回合获胜。5
转2号。0
转2号。1
转2号。2
转2号。3
转2号。4
转2号。5
2 玩家获胜
1 玩家获胜
ps 我想要什么通常可能吗?)))
pss 我只需要以某种方式做两个具有时间依赖性的相关动画

标签: javascriptrecursiontimer

解决方案


这是您的预期行为吗?为了简单和更快的测试运行,我已经更正了您实现的游戏逻辑,并在各处放置了 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, 500, 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, 3000, 0);

无论如何,setTimeout最终将并行运行,因此如果您的目的是创建异步代码,其中一个函数必须等待另一个函数 - 最好使用 async/await 和 promise,因为它们正是为此而生的。检查下面的代码并阅读评论

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


推荐阅读