延迟For循环

时间:2014-05-27 16:12:36

标签: javascript settimeout

我正在尝试创建一个FOR循环,每隔1000毫秒移除一个元素,而不是瞬间冲过数组并执行操作。

我这样做是出于性能原因,因为正常通过循环会冻结我的UI。

 function removeFunction (i,selected) {
    selected[i].remove(); 
    }

function startLoop() {
        var selected = paper.project.selectedItems;
        for (var i = 0; i < selected.length; i++) {
            if (selected[i].name === "boundingBoxRect") continue;
          setTimeout(removeFunction(i,selected),1000)

        }

    }

似乎没有任何延迟地调用所选的[i] .remove()方法。这是为什么?由于我设置的超时时间为1000毫秒不应该删除每个项目间隔1000毫秒的项目吗?

注意

在上面的代码中,我正在跳过一个名为boundingBoxRect的项目,因为我不想删除它。只是说明这一点,所以没有混淆

2 个答案:

答案 0 :(得分:3)

只需将其转换为递归函数:

function removeFunction (i, selected) {
    // If i is equal to the array length, prevent further execution
    if (i === selected.length)
        return;

    // Remove ith child of selected array
    selected[i].remove();

    // Trigger same function after 1 second, incrementing i
    setTimeout(function() {
        removeFunction(++i,selected)
    }, 1000);
}

// Trigger the function to begin with, passing in 0 as i
removeFunction(0, paper.project.selectedItems);

以下是JSFiddle demo(使用console.log代替selected[i].remove(),因为您没有提供该功能的定义);

答案 1 :(得分:1)

  

似乎没有任何延迟地调用所选的[i] .remove()方法。那是为什么?

因为那是你告诉它的事情。 setTimeout(removeFunction(i,selected),1000) 立即调用 removeFunction并将其返回值传递到setTimeout,完全按照foo(bar()) 调用的方式 {{1并将其返回值传递给bar

您可以使用构建器功能获得所需的效果:

foo

...其中setTimeout(buildRemover(i,selected),1000); 是:

buildRemover

请注意function buildRemover(index, array) { return function() { removeFunction(index, array); }; } 如何创建一个关闭buildRemoverindex变量的函数。然后它返回对该函数的引用,这是通过array计划的。发生超时时,将调用该生成的函数,并使用适当的值调用setTimeout

你也可以使用ES5 removeFunction

做类似的事情
Function#bind

setTimeout(removeFunction.bind(null, i, selected),1000); 返回一个新函数,在调用时,将调用原始函数(上面的Function#bind)使用给定的removeFunction值(在我们的示例中为this)和参数