If you want an equal interval, your loop is fine, you just need to fix the math for calculating the timeout:
const btn = document.getElementById('btn');
btn.addEventListener('click', function(){
for (let index = 10; index > 0; index--) {
setTimeout(() => {
console.log(index)
}, 1000*(10-index));
}
})
<div class="app">
<button id="btn">click</button>
</div>
That will count down from 10 to 1 once every second, just change the 1000 as needed if you want it to be faster or slower.
Note that the order of the loop doesn't actually matter here (aside from a few ms difference in execution time) since it's asynchronous - you could use a non-reversed loop and still get the same result to the human eye.
Answer from John Montgomery on Stack OverflowIf you want an equal interval, your loop is fine, you just need to fix the math for calculating the timeout:
const btn = document.getElementById('btn');
btn.addEventListener('click', function(){
for (let index = 10; index > 0; index--) {
setTimeout(() => {
console.log(index)
}, 1000*(10-index));
}
})
<div class="app">
<button id="btn">click</button>
</div>
That will count down from 10 to 1 once every second, just change the 1000 as needed if you want it to be faster or slower.
Note that the order of the loop doesn't actually matter here (aside from a few ms difference in execution time) since it's asynchronous - you could use a non-reversed loop and still get the same result to the human eye.
If you use promises and async/await you can avoid the setTimeout overload and have precise control. The difference between this and John Montgomery's answer is this doesn't care how many times you loop. Do 10000 if you want, you won't get 10000 setTimeouts running at the same time.
const btn = document.getElementById('btn');
const wait = time=>new Promise(resolve=>setTimeout(resolve,time))
btn.addEventListener('click', async function(){
for (let index = 10; index > 0; index--) {
await wait(1000)
console.log(index)
}
})
<div class="app">
<button id="btn">click</button>
</div>
Async functions allow you to use the await keyword. This is a neat new feature in javascript that let's you write async code (like setTimout) as if it was sync.
const wait = time=>new Promise(resolve=>setTimeout(resolve,time))
is a fairly common helper function developers keep around for times you need to just wait some amount of time and then do something. By await'ing the wait(1000) function, I hang the execution of the loop until the time is done.
javascript - Are loops really faster in reverse? - Stack Overflow
javascript - How do i loop through an array backwards? - Stack Overflow
For loop backwards
Best way to loop back and forth though an array?
Videos
It's not that i-- is faster than i++. Actually, they're both equally fast.
What takes time in ascending loops is evaluating, for each i, the size of your array. In this loop:
for(var i = array.length; i--;)
You evaluate .length only once, when you declare i, whereas for this loop
for(var i = 1; i <= array.length; i++)
you evaluate .length each time you increment i, when you check if i <= array.length.
In most cases you shouldn't even worry about this kind of optimization.
This guy compared a lot of loops in javascript, in a lot of browsers. He also has a test suite so you can run them yourself.
In all cases (unless I missed one in my read) the fastest loop was:
var i = arr.length; //or 10
while(i--)
{
//...
}
Simple, loop the other way. Instead of i++ use i--:
for(i = 0; i < array.length; i++){
// do something with array[i]
}
// you go backwards:
for(i = array.length - 1; i >= 0; i--){
// do something with array[i]
}
Option 1
var arr = [1, 2, 3, 4, 5];
for (var i = arr.length - 1; i >= 0; i--) {
console.log(arr[i]);
}
Option 2
var arr = [1, 2, 3, 4, 5];
arr.slice().reverse().forEach((item) => {
console.log(item);
});
Hi, I've got a modal I've made on a site but I would like to have a functional image gallery that goes back and forth though a list of local images no matter that size of the array. My problem is I have the modal, images and button events set but the function messes up as it get to the end of the array of images or the start or when i'm moving forward/backwards then press the reverse as I have to pres the button twice for it to work .
I'd post the code but it's so messed up I'd rather know the best clean solution for this issue.
so
I need the list of images thats in the array to loop as it get to the end/start of the list (using a previous and next button).
1a. As it get to the end of the list. 1b. As it get to the start needed to go back to the end.
I've delayed coding for a while as its frustrated me please help :/
let arr = [1, 2, 3];
arr.slice().reverse().forEach(x => console.log(x))
will print:
3
2
1
arr will still be [1, 2, 3], the .slice() creates a shallow copy.
Just use a for loop. Start at the end of the array and go backwards from there.
const array = ['blastoff', 1, 2, 3];
for (let index = array.length - 1; index >= 0; index--) {
const element = array[index];
console.log(element);
}
var num = 10,
reverse = false;
if(!reverse) for( var i=0;i<num;i++) log(i);
else while(num-- ) log(num);
// to avoid duplication if the code gets long
function log( num ) { console.log( num ); }
EDIT:
As noted in the comments below, if i is not declared elsewhere and you do not intend for it to be global, then declare it with the other variables you declared.
And if you don't want to modify the value of num, then assign it to i first.
var num = 10,
reverse = false,
i;
if(!reverse) for(var i=0;i<num;i++) log(i); // Count up
else {var i=num; while(i--) log(i);} // Count down
function log( num ) { console.log( num ); }
Try use 2 loops:
if (reverse) {
for(i=num-1;i>=0;i--){
console.log(i)
}
}
else {
for(i=0;i<num;i++){
console.log(i)
}
}