Reputation: 22989
I am trying to create a FOR loop that removes an element every 1000ms instead of rushing instantaneously through the array and perform the operations.
I am doing this for reasons of performance since going normally through the loop freezes my 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)
}
}
It seems that the selected[i].remove() method is getting called without any delay. Why is that? Since I have set a Timeout of 1000ms shouldn't the items get removed with 1000ms interval between each?
Note
In the code above, I am skipping an item called boundingBoxRect since I don't want to remove that. Just stating this so there is no confusion
Upvotes: 1
Views: 90
Reputation: 1075625
It seems that the selected[i].remove() method is getting called without any delay. Why is that?
Because that's what you're telling it to do. setTimeout(removeFunction(i,selected),1000)
calls removeFunction
immediately and passes its return value into setTimeout
, exactly the way foo(bar())
calls bar
and passes its return value into foo
.
You can get the effect you want by using a builder function:
setTimeout(buildRemover(i,selected),1000);
...where buildRemover
is:
function buildRemover(index, array) {
return function() {
removeFunction(index, array);
};
}
Note how buildRemover
creates a function that closes over the index
and array
variables. Then it returns a reference to that function, which is what gets scheduled via setTimeout
. When the timeout occurs, that generated function is called, and it calls removeFunction
with the appropriate values.
You can also do something similar using ES5's Function#bind
:
setTimeout(removeFunction.bind(null, i, selected),1000);
Function#bind
returns a new function that, when called, will call the original (removeFunction
above) use the given this
value (null
in our example) and arguments.
Upvotes: 1
Reputation: 128836
Simply turn it into a recursive function:
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);
Here's a JSFiddle demo (using console.log
instead of selected[i].remove()
, as you haven't provided a definition for that function);
Upvotes: 3