There is a setTimeout inside the for loop:
for (var i = 1; i <= 5; i++) { setTimeout(function() { console.log(i); }, i * 1000); } I want to show the numbers 1 , 2 , 3 , 4 , 5 , but it shows 6 , 6 , 6 , 6 , 6 . Why?
There is a setTimeout inside the for loop:
for (var i = 1; i <= 5; i++) { setTimeout(function() { console.log(i); }, i * 1000); } I want to show the numbers 1 , 2 , 3 , 4 , 5 , but it shows 6 , 6 , 6 , 6 , 6 . Why?
The point is that the function is executed after the cycle ends. Therefore, i is equal to 6 when console.log(i) is executed for the first time.
If it is still not clear, here is a similar example in pseudocode:
Π£ ΠΌΠ΅Π½Ρ 1 ΠΊΠ°ΠΌΠ΅Π½Ρ. Π§Π΅ΡΠ΅Π· ΠΌΠΈΠ½ΡΡΡ ΡΠΊΠ°ΠΆΠΈ, ΡΠΊΠΎΠ»ΡΠΊΠΎ Ρ ΠΌΠ΅Π½Ρ ΠΊΠ°ΠΌΠ½Π΅ΠΉ. ΠΠ°ΠΉ ΠΌΠ½Π΅ ΠΊΠ°ΠΌΠ΅Π½Ρ ΡΠ΅ΠΉΡΠ°Ρ. Π§Π΅ΡΠ΅Π· 2 ΠΌΠΈΠ½ΡΡΡ ΡΠΊΠ°ΠΆΠΈ, ΡΠΊΠΎΠ»ΡΠΊΠΎ Ρ ΠΌΠ΅Π½Ρ ΠΊΠ°ΠΌΠ½Π΅ΠΉ. ΠΠ°ΠΉ ΠΌΠ½Π΅ ΠΊΠ°ΠΌΠ΅Π½Ρ ΡΠ΅ΠΉΡΠ°Ρ. It turns out that now I will give 2 stones, in the end I will have 3. In a minute, he will say how many stones I have (ie, 3), and in two minutes he will say again that I have 3 stones.
i to the output function at each iteration. This is the most common solution. for(var i = 1; i <= 5; i++) { (function(i) { setTimeout(function() { console.log(i); }, i * 1000); })(i); } Creating many of the same functions is not very good, you can raise this function above:
function pass(i) { return function () { console.log(i); } } for(var i = 1; i <= 5; i++) { setTimeout(pass(i), i * 1000); } (function f(i) { if (i > 5) return; setTimeout(function() { console.log(i); f(i + 1); }, 1000); })(1); Function.prototype.bind() to create a new function at each iteration. This is shorter than the first option, but IE8 and below do not support .bind . for (var i = 1; i <= 5; i++) { setTimeout(function(i) { console.log(i); }.bind(null, i), i * 1000); } setTimeout . This is supported by all modern browsers, but if we are talking about old ones, then it is worth checking out. for(var i = 1; i <= 5; i++) { setTimeout(function (i) { console.log(i); }, i * 1000, i); } I note that now the functions in the loop are no different from each other, so you can make one function:
function doSmth(i) { console.log(i); } for(var i = 1; i <= 5; i++) { setTimeout(doSmth, i * 1000, i); } Use let . This is a convenient option, but it is a new feature in ECMAScript 2015, so it still does not work in most browsers. If you want to use ECMAScript 2015 to the point that browsers support it, I recommend trying Babel .
Warning: some browsers (for example, IE 11) support let , but do not support it in the for loop.
for (let i = 1; i <= 5; i++) { setTimeout(function() { console.log(i); }, i * 1000); } setInterval . - Regenti + 1 in setTimeout . Could you explain? And yes, in this case the setInterval option is convenient, but I wanted an answer that works in the general case. Maybe instead of setTimeout , there is an AJAX request or another asynchronous function. - Peter OlsonsetInterval will work exactly the same. - RegentAsync solution
const intArray = [1, 2, 3, 4, 5]; async.eachSeries(intArray, function(i, callback) { setTimeout(function() { console.log(i); callback(); }, i * 1000); }, function(err) { // if any of the file processing produced an error, err would equal that error if( err ) { console.log('An error occured. All processing has stopped'); } else { console.log('Whole array processed successfully'); } }); <script src="https://cdnjs.cloudflare.com/ajax/libs/async/2.4.0/async.js"></script> Source: https://ru.stackoverflow.com/questions/961718/
All Articles