problem when using += in setInterval to continually increment a variable [duplicate] - javascript

This question already has answers here:
What is the scope of variables in JavaScript?
(27 answers)
Closed 3 years ago.
here are two questions about the exercise that I am doing for practicing of setInterval fuction
from following code, I tried to print out the variable which is self-adding by 10 within 1000 milliseconds, but when I ran it, in the console of browser, it only showed 10 times of same word "num", how do I figure it out ?
$(function() {
var timmer;
GoCount();
function GoCount() {
timmer = setInterval(function() {
var num = 0;
num += 10;
console.log(num);
}, 1000);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
and the second question is what's the difference between setInterval and for loop

As #Carsten Løvbo Andersen 's comment, you should make the num as global variable to be able to keep the previous value.
$(function() {
var timmer;
var num = 0;
GoCount();
function GoCount() {
timmer = setInterval(function() {
num += 10;
console.log(num);
}, 1000);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Each time you the function runs you set "num" back to zero and add 10. You need to declare the num as 0 outside of that function, in the same place as "timmer".

You can pass your variable as function params then you can change the start number as well.
$(function() {
var timmer;
GoCount(0);
function GoCount(num) {
timmer = setInterval(function() {
num += 10;
console.log(num);
}, 1000);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
codes inside a loop will be run without delay, but in setInterval you can set that how much time should be between running the codes in your scope.

Create the num variable outside the setInterval function. In your code the num variable is declare as new variable and assigned the value to 0 each time the setInterval executes.
$(function() {
var timmer;
GoCount();
function GoCount() {
var num = 0;
timmer = setInterval(function() {
num += 10;
console.log(num);
}, 1000);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

You can make your code simpler by creating an IIFE like this:
((num) => setInterval(() => {
num += 10
console.log(num)
}, 1000))(0) // <- Initialize the `num` variable here

If you want to increase the num by 10 with each iteration you need to move out the num variable (as #Carsten Løvbo Andersen said):
$(function() {
var num = 0;
var timmer;
GoCount();
function GoCount() {
timmer = setInterval(function() {
num += 10;
console.log(num);
}, 1000);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
See https://jsfiddle.net/f8hn4xrw/ for a working example

Related

Loop through a function every 5 seconds then reset after the last time

I need to loop through the function switch_tiles so the function will run as switch_tiles(1); switch_tiles(2); etc... but it needs to be i++ every 5 seconds. I've tried putting the interval inside the loop but that didn't help either. Also, after i = 5 I want it to reset.
window.setInterval(function(){
for(var i = 1; i < 5; i++){
switch_tiles(i);
}
}, 5000);
This is all the function does so that's not too important to the question. Just added for context.
function switch_tiles(n){
var last = $('.active').attr('id');
$('#'+last).removeClass('fas');
$('#'+last).removeClass('active');
$('#'+last).addClass('far');
$('.active_tile').fadeOut();
$('#tile_' + n).fadeIn();
$('#circle_' + n).removeClass('far');
$('#circle_' + n).addClass('fas');
$('#circle_' + n).addClass('active');
}
Try this:
var i = 1;
function myFunction() {
if (i > 5)
i = 1;
switch_tiles(i++);
window.setTimeout(myFunction, 5000);
}
myFunction();
var i = 1;
window.setInterval(function(){
if (i == 5){
//reset over here.
}
switch_tiles(i);
i++;
}, 5000);
i = 0;
window.setInterval(function() {
i++;
if(i > 5){
i = 1;
}
switch_tiles(i)
}, 5000);
You just need to tell i to be whatever number you want at any time. Also, this all depends on if you have your tiles at base-0 or base-1. You would put your i++ before or after the switch_tiles()
What you want is probably something like that:
window.setInterval(function(){
switch_tiles(i++);
if (i>5) i=0;
}, 5000);
This will run the function every 5 sec, increasing the parameter every time.
Note that this uses a global variable window.i so it's sort of dirty...

how to decrease number by using var

I have a variable equal to number, so I want decrease this variable value every second.
in this code it is print the same number over and over, although I have written
(n--)
var x = setInterval(function() {
var n = 50;
console.log(n--);
}, 1000);
my question how I can decrease it?
You could use a IIFE with a closure about the value. Tha advantage is to use a local variable without polluting the global space.
var x = setInterval(function(n) {
return function() {
console.log(n--);
};
}(100), 1000);
And here is one without the need of a global variable but using IIFE:
var x = setInterval(
(startValue => () => {
console.log(startValue--);
})(100),
1000
);
Checkout this: it will stop when x will equals to zero
var x = 100;
var handler = setInterval(function(){
x--;
console.log(x);
if(x === 0)
clearInterval(handler)
} , 1000)
Your code issue is that you put the -- sign after and It should be before(--n) and It also you have declared var n = 50 inside to loop of setInterval, at this way each time that It's executed n variable always is 50, you should to put this varible at the start of yout code.
var n = 50;
var x = setInterval(function() {
console.log(--n);
}, 1000);

Use each value of a for loop before the loop finishes [duplicate]

This question already has answers here:
How do JavaScript closures work?
(86 answers)
Closed 5 years ago.
I have a function that gets values using for loops and puts them into 1 variable. This variable is them stuck in a form where its is then submitted. But the problem is that the for loop would finish looping by the time the value is entered and submitted. So everytime I test it, the variable "value" = 9999. Can anyone please tell me how to add 1 to variable every time the function loops? Thanks in advance.
function myFunction() {
var value1;
var value2;
var value3;
var value4;
var value;
for (value1 = 0; value1 < 10; value1++) {
for (value2 = 0; value2 < 10; value2++) {
for (value3 = 0; value3 < 10; value3++) {
for (value4 = 0; value4 < 10; value4++) {
value = value1.toString() + value2.toString() + value3.toString() + value4.toString() + '#2018';
document.getElementById('pswd').value = value;
document.getElementById('uid').value = 'test';
document.getElementById('commentForm').submit();
}
}
}
}
}
var loop = setInterval(function() {
myFunction();
}, 2000);
If I'm reading your question correctly, you would like the number to go up by one each time the interval callback is called? You can accomplish this by keeping track of the value outside the function, and do a single increment each time the callback is called. However, you are using 4 variables to basically count from 0 to 9999. You can simplify that a lot by using one variable to increment. Then you can left pad it with zeroes. That would look like this.
var value = 0;
function myFunction() {
var pswd = value.toString().padStart(4, 0) + '#2018';
document.getElementById('pswd').value = pswd;
document.getElementById('uid').value = 'test';
document.getElementById('commentForm').submit();
value++;
if(value > 9999) {
value = 0;
}
}
var loop = setInterval(myFunction, 2000);
If you can't use padStart, you can use slice instead. You can replace that line with the following.
var pswd = ('0000' + value).slice(-4) + '#2018';

Looping using setInterval

I am trying to make a counter that counts from 10 to 0 using JavaScript with a loop function and setInterval but this does not work for me:
function count() {
var i;
for (i = numbers.textContent; 0 <= i; i--) {
numbers.textContent = i;
}
}
setInterval(count, 1000);
<div id="countDown">10</div>
You are doing a for loop inside setInterval
var numbers = document.getElementById('countDown');
function count() {
var i;
if(numbers.textContent>0)
numbers.textContent=numbers.textContent-1;
else
clearInterval(handle);
/*for(i=numbers.textContent; 0<=i; i--){
console.log(i)
numbers.textContent= i;
}*/
}
var handle= setInterval(count, 1000);
<div id="countDown">10</div>
This should work:
parseInt(numbers.textContent)
And there are many more:
You need a global variable.
You don't need a for loop for this.
Change the condition.
<div id="countDown">10</div>
<script>
var numbers = document.getElementById('countDown');
var interval = setInterval(count, 1000);
function count() {
var count = parseInt(numbers.textContent);
count--;
if (count == 0) {
clearInterval(interval);
}
numbers.textContent = count;
}
</script>
If you want to see it by loops, you can do using setTimeout:
<div id="countDown">10</div>
<script>
var numbers = document.getElementById('countDown');
function count() {
var count = parseInt(numbers.textContent);
count--;
numbers.textContent = count;
}
for (var i = 1; i <= parseInt(numbers.textContent); i++)
setTimeout(count, 1000 * i);
</script>
the first time count is called, the for loop will run till numbers.textContent is 0(and it's so fast that your eyes just missed that change on the page), and the 2nd call, 3rd call is just iterate around 0, nothing is changed.
BTW, after your counting is finished(or maybe you should give it a stop condition, reference to the DOC), you should unregister the interval, cause it never end by default.

Javascript increment not working

Well I did not know what exactly would be a good title for this because it is a most peculiar situation or I'm abnormally dumb.
Here's what im trying to do.
Create a simple <meter> tag which is new in HTML5. The main issue is with my javascript. Im trying to increment the value of the meter tag gradually in my javascript. But somehow it doesn't work the way i want.
JavaScript.
for (var i = 0; i <= 10; i++) {
var a = document.getElementById("mtr1");
setTimeout(function () {
console.log(i);
a.value = i;
}, 250);
}
I'm trying to increase the value of the meter gradually every 250 ms.This doesn't happen. Instead the meter jumps straight to 10.
What interested me was the value of i that i got in the console. I got instances of 10, instead of 1,2,3...10.
Why does this happen?
FIDDLE
It's a JavaScript closures' classic. Here i is an actual reference to the variable, not its copy. After you've iterated through the loop it has the value of 10, that's why all log invocations write 10 to log.
This should work better:
for (var i = 0; i <= 10; i++) {
var a = document.getElementById("mtr1");
setTimeout(function (i) {
return function() {
console.log(i);
a.value = i;
};
}(i), 250 * i);
}
Here the most inner i is the setTimeout's callback argument, not the variable which you've declared in the loop body.
You should read more about closures in JavaScript. When a variable gets closed over, it's the same exact variable, not a copy. Since setTimeout is asynchronous, the whole loop finishes before any of the functions run, therefore the i variable will be 10 everywhere.
DEMO
function incMtrAsync(max, delay, el) {
if (el.value++ < max) {
setTimeout(incMtrAsync.bind(null, max, delay, el), delay);
}
}
incMtrAsync(10, 250, document.getElementById("mtr1"));
The above implementation implements the loop using a recursive approach. Everytime inMtrAsync is called, it checks if the value of the meter reached the max value, and if not, registers another timeout with a callback to itself.
If you want to delay the initial increment as well, just wrap the first call in another timeout.
setTimeout(incMtrAsync.bind(null, 10, 250, document.getElementById("mtr1")), 250);
Nobody used setInterval, so here's my solution ( http://jsfiddle.net/Qh6gb/4/) :
var a = document.getElementById("mtr1");
var i = 0;
var interval = setInterval(function () {
console.log(i);
a.value = ++i;
if (i == 10) {
clearInterval(interval);
}
}, 250);
The problem you describe happens before the asyncronous call to setTimeout in your original version sees a value of 10 for i because that is its value at the moment the callback is executed.
So, this is a problem with the scope of the closure, to make it work you should make it like this:
for (var i = 0; i <= 10; i++) {
var a = document.getElementById("mtr1");
(function (i, a) {
setTimeout(function () {
console.log(i);
a.value = i;
}, 250);
})(i, a);
}
also, since a is always the same, this should be better:
var a = document.getElementById("mtr1");
for (var i = 0; i <= 10; i++) {
(function (i) {
setTimeout(function () {
console.log(i);
a.value = i;
}, 250);
})(i);
}
If then you want to see the counter "ticking up", this will make it visible:
var a = document.getElementById("mtr1");
for (var i = 0; i <= 10; i++) {
(function (i) {
setTimeout(function () {
console.log(i);
a.value = i;
}, 1000 * i);
})(i);
}
See http://jsfiddle.net/LDt4d/
It happens because you called setTimeout, which is "asynchronous". So setTimeout is called 10times but after whole loop is done then it is executed. Therefore, i = 10 in each call...
http://jsfiddle.net/Qh6gb/9/
there is the solution:
var i = 1,
meter = document.getElementById("mtr1");
function increase() {
meter.value = i++;
console.log(i);
if(i<=10) {
setTimeout(increase, 250);
}
}
setTimeout(increase, 250);
you can use timeout jquery plugin:. It is easier
However you should calculate your timeout ,
For you ,timeout=250*max=250*10=2500
So
$('meter').timeout(2500);
Demo
Run for loop inside the function instead of declaring a closure in every step of the loop.
JSFIDDLE: http://jsfiddle.net/Qh6gb/3/
var a = document.getElementById("mtr1");
setTimeout(function () {
for (var i = 0; i < 10; i++) {
console.log(i);
a.value = i;
}
}, 250);
I hope I understand right. Please try and tell me if you got solution.
var count = 0;
function increment(){
document.getElementById("meter").value = count;
count++;
if(count ==10)
count=0;
}
setInterval(increment, 250);
Please check with jsFiddle
You're creating multiple functions that are all being set off at the same time.
Multiply the timer by i for correct delay.
for (var i = 0; i <= 10; i++) {
var a = document.getElementById("mtr1");
setTimeout(function () {
console.log(i);
a.value = i;
}, 250 * i);
}

Categories