![](/img/trans.png)
[英]Converting a JavaScript function to PHP and it doesn’t produce the expected output
[英]JavaScript: setInterval() doesn't produce expected output
請在下面查看我的代碼,我不知道為什么它會產生預期的輸出。 我認為我使用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
由於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); }) } })();
不知道您要用此代碼完成什么。 但請嘗試以下方法。 您可以控制台記錄您的要求。 做改變,如你所願,
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); });
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); })();
您有一個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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.