I'm trying to run multiple timers given a variable list of items. The code looks something like this:
var list = Array(...);
for(var x in list){
setInterval(function(){
list[x] += 10;
console.log(x + "=>" + list[x] + "\n");
}, 5 * 1000);
}
The problem with the above code is that the only value being updated is the item at the end of the list, multiplied by the number of ite开发者_如何学编程ms in the list.
Can anyone offer a solution and some explanation so I know why it's behaving this way?
var list = [1, 2, 3, 4, 5];
for (var i = 0, len = list.length; i < len; i += 1) {
(function(i) {
setInterval(function() {
list[i] += 10;
console.log(i + "=>" + list[i] + "\n");
}, 5000)
})(i);
}
Here is the working code:
var list = [1, 2, 3, 4, 5];
for (var i = 0, len = list.length; i < len; i += 1) {
(function(i) {
setInterval(function() {
list[i] += 10;
console.log(i + "=>" + list[i] + "\n");
}, 5000)
})(i);
}
Here the index i is stored in an anonymous function, so that it is not overwritten by consecutive loops. setInterval function in your code keeps the reference only to the last value of i.
So, a few things:
- Most importantly, the callback function you've passed to
setInterval()maintains a reference toxrather than the snapshot value ofxas it existed during each particular iteration. So, asxis changed in the loop, it's updated within each of the callback functions as well. - Additionally,
for...inis used to enumerate object properties and can behave unexpectedly when used on arrays. - What's more, I suspect you really want
setTimeout()rather thansetInterval().
You can pass arguments to your callback function by supplying additional arguments to setTimout():
var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
Numbers will be passed by value rather than reference. Here's an example:
var list = [1,2,3,4];
for (var x = 0, ln = list.length; x < ln; x++) {
setTimeout(function(y) {
console.log("%d => %d", y, list[y] += 10);
}, x * 500, x); // we're passing x
}
You can combine forEach and setTimeout to loop over the array with the interval.
let modes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let interval = 1000; //one second
modes.forEach((mode, index) => {
setTimeout(() => {
console.log(mode)
}, index * interval)
})
You don't have to use a for cycle with the setInterval statement. Try this:
var list = Array(...);
var x = 0;
setInterval(function() {
if (x < list.length;) {
list[x] += 10;
console.log(x+"=>"+list[x]);
}
else return;
x++;
}, 5000);
I don't know how to do this with a for loop but this code here will print out each element in an array at timed intervals:
function displayText(str) {
$('.demo').append($('<div>').text(str));
}
var i = 0;
var a = [12, 3, 45, 6, 7, 10];
function timedLoop() {
setTimeout(function () {
displayText(a[i]);
i++;
if(i < a.length) {
timedLoop();
}
}, 2000)
}
timedLoop();
Using a bit of jquery to show it in the browser.
Please look at this simplest solution. It does work with forloop too. It looks like an interval but it is a timeout increased for each iteration. For each iteration setTimeout doubles.
for(let i=1; i<=10;i++){
setTimeout(function(){
console.log(i)
},i*1000)
}
If you have JSON array and jQuery included, you can use:
$.each(jsonArray, function(i, obj) {
setInterval( function() {
console.log(i+' '+obj);
}, 10);
});
加载中,请稍侯......
精彩评论