Javascript:Push 列表中的项目并延迟打印

Javascript:Push items in a list and print them with delay

我想使用 for 循环推送列表中的项目并延迟打印每一步。相反,我在每次迭代中都得到完整的 list.I 猜测这是一个范围问题,但我无法找到解决方案。

这是我的代码:

function printNumber(num,i){

    setTimeout(()=>console.log(num),500*i);
}


let numbers = [50];

for(let i=1; i<=10; i++){

    printNumber(numbers,i);
    numbers.push(i);
}


你交出数组而不是值。

printNumber(i, i);
//          ^

function printNumber(num, i) {
    setTimeout(() => console.log(num), 500 * i);
}

let numbers = [50];

for (let i = 1; i <= 10; i++) {
    printNumber(i, i);
    numbers.push(i);
}

如果你想显示所有收集到的数字,你可以复制数组。

function printNumber([...num], i) {
    setTimeout(() => console.log(...num), 500 * i);
}

let numbers = [50];

for (let i = 1; i <= 10; i++) {
    numbers.push(i);
    printNumber(numbers, i);
}

我认为您可能正在寻找类似于以下代码段中的内容。该数组包括每次迭代的所有值,因为循环在 setTimeout 开始打印之前运行完成。

由于数组存储为引用,num 正在被 numbers.push(i) 变异。

每次循环向函数传递一个新数组即可解决此问题。

function printNumber(num,i){

    setTimeout(()=>console.log(num),500*i);
}


let numbers = [50];

for(let i=1; i<=10; i++){
    // Create new array when you pass it here
    printNumber([...numbers],i);
    numbers.push(i);
}

那是因为 Javascript passes arrays by reference*,这意味着在循环结束后运行很长时间的回调将全部指向相同的、更新的数组值。

每次都需要复制数组才能使用中间状态。您可以这样调用 printNumber

printNumber([...numbers], i);

这样它将创建数组的新副本并且迭代不会相互混淆。

* 请参阅 进一步说明

setTimeout 是一个定时器。它会延迟执行任何 INSIDE。它不会暂停其余代码。到 console.log 执行时,您的数组已完成。所以它将打印完成的数组。

let numbers = [50];

for(let i=1; i<=10; i++){
     
     setTimeout(()=>{  
       console.log(numbers, i)
       numbers.push(i); 
       
     },500*i);
}