请在下面查看我的代码,我不知道为什么它会产生预期的输出。我认为我使用setInterval()和setTimeout的方式是错误的。不知何故,该过程不会从上到下按1个顺序进行。似乎有3个线程并行运行。我该如何解决?谢谢。
(function() {
var nums = [1, 2, 3];
nums.forEach(
(e) => {
console.log(e);
var frame = 0;
let loop = setInterval(function() {
if (frame === 3)
clearInterval(loop);
console.log(e + " frame " + frame);
frame++;
}, 1000);
let wait = setTimeout(function() {
console.log(e + " 2 second passed");
}, 2000);
}
)
})();
预期输出:
1
1 frame 0
1 frame 1
1 frame 2
1 2 seconds passed
2
2 frame 0
2 frame 1
2 frame 2
2 2 seconds passed
3
3 frame 0
3 frame 1
3 frame 2
3 2 seconds passed
实际输出:
1
2
3
1 frame 0
2 frame 0
3 frame 0
1 frame 1
1 2 second passed
2 frame 1
2 2 second passed
3 frame 1
3 2 second passed
1 frame 2
2 frame 2
3 frame 2
1 frame 3
2 frame 3
3 frame 3
答案 0 :(得分:2)
由于Javascript是异步的,因此您需要某种方式来等待每个间隔和超时完成,然后再运行下一个。
一种方法是使用async/await并将间隔和超时包装在promise中。
(async function() {
var nums = [1, 2, 3];
for (const e of nums) {
console.log(e);
let frame = 0;
await new Promise(resolve => {
let loop = setInterval(function() {
if (frame === 3) {
clearInterval(loop);
resolve();
} else {
console.log(e + " frame " + frame);
frame++;
}
}, 100);
})
await new Promise(resolve => {
let wait = setTimeout(function() {
console.log(e + " 2 second passed");
resolve();
}, 200);
})
}
})();
答案 1 :(得分:1)
不知道您将用此代码完成什么。但请尝试以下方法。您可以控制台记录您的要求。做改变以您的喜好,
let nums = [1, 2, 3];
const timesecs = 1000;
const timeOut = (num) => {
setTimeout(
() => {
console.log(num);
nums.forEach(
(item, index) => {
console.log(num + " frame " + index);
}
)
//console.log(`${num} ${num+1} seconds passed`);
console.log(`${num} 2 seconds passed`);
},
num * timesecs
)
}
nums.forEach((num) => {
timeOut(num);
});
答案 2 :(得分:1)
JavaScript无法以这种方式工作。您需要首先了解ASYNC操作和回调的概念。 Aysnc操作(如setTimeout和setInterval)在移动到代码的下一行之前,不必等待其回调函数完成。他们只是将执行光标移到下一行。您的setInterval函数将在1000毫秒后完成其回调执行。
添加了新功能,例如等待和异步功能。您可能希望研究它们以实现所需的目标。
您正在运行的for循环应该在时间间隔之内,而不是您正在做什么。
(function () {
var nums = [1, 2, 3];
var ind = 0;
let loop = setInterval(function(){
if(ind === 2){
clearInterval(loop);
}
console.log(nums[ind]);
nums.forEach(e => {
console.log(nums[ind] + " frame " + e);
});
console.log(nums[ind] + " 2 seconds passed");
ind++;
}, 2000);
})();
答案 3 :(得分:1)
您有一个forEach循环,该循环将循环3次。在第一次迭代中,它将:
然后,循环的第二次迭代会在第一次迭代后立即发生,因此它将再次发生:
最后,第三次迭代将立即发生,它将:
接下来,所有新创建的三个时间间隔将在循环结束后约1秒执行。每个时间间隔将比前一个时间间隔稍稍执行。每个变量都在变量frame
周围包含一个“闭包”(即,当它们被创建时,它们都被“捕获”在设置为0
的帧中,因此它们都console.log(0)
。>
在下一秒,这3个间隔中的每一个将尝试再次运行(现在每个间隔都带有frame === 1
),并且3个超时也将尝试运行。请注意,每个超时还形成了一个“关闭”,在创建之时将e
的值锁定。您最终会得到一些间隔的执行时间,并混合了超时的执行时间。
这3次超时仅一次发生。
输出的其余部分是连续执行的3个间隔的集合,每个集合之间有2秒的间隔。
您只需使用一个间隔(无循环),设置为每秒触发并打印一些内容,即可实现输出。我不确定要打印这些语句间隔几秒的要求,因此我无法生成所需的确切代码,但是有些东西会在最佳时机生成您想要的输出:
var num = 1;
var frame = 0;
var loop = setInterval( function() {
if (frame === 0) {
console.log(num);
}
if (frame >= 0 && frame <= 2) {
console.log(num + " frame " + frame);
}
if (frame === 4) {
console.log(num + " 2 seconds passed");
num++;
frame = -1;
}
if (num > 3) {
clearInterval(loop);
}
frame++;
}, 1000);