javascript - 递归 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 我只需要以某种方式做两个具有时间依赖性的相关动画
解决方案
这是您的预期行为吗?为了简单和更快的测试运行,我已经更正了您实现的游戏逻辑,并在各处放置了 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();
推荐阅读
- regex - 正则表达式匹配两个字符之间任意位置的某些字符
- regression - 以最少的计算成本考虑数据序列中的奇异偏移
- javascript - 从数组对象中获取唯一值(复杂)
- r - 如何避免此错误:Can't geocode an object of class `NULL?
- spring - 使用 OAuth2 进行 Spring 生产就绪身份验证
- javascript - Github API GET Approved Pull Request 评论列表
- laravel - Laravel 8 存储链接没有生效?
- location - 自定义纬度经度上的 Grib 插值
- reactjs - 从 Lighthouse for Google Recaptcha 和 Google Maps API 解决“删除未使用的 Javascript”的最合适方法
- javascript - React Routes 和 Components 道具组合