how to decrease number by using var - javascript

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);

Related

Run code with a different outcome every 30 seconds

I have 2 variables called var1, and var2:
var var1 = 'foo';
var var2 = 'bar';
I'd like to be able to log one of these variables to the console every 30 seconds, with the variables alternating being logged (here's some pseudo-code):
Log var1 to console
Wait 30 seconds
Log var2 to console
Wait 30 seconds
Repeat
Any way to do this? I believe I should be doing something related with setInterval, but my solution:
setInterval(function() {
console.log(var1);
setTimeout(() => {
console.log(var2);
}, 30000);
}, 60000);
Doesn't seem to be the best solution. Is there a more efficient way to do this?
Just keep counter that enables you to alternate.
var counter = 0;
var var1 = "ONE!";
var var2 = "TWO!";
var frequency = 1000; //1000 is for illustration for the example
setInterval(function() {
if( counter++ % 2 == 0 ) {
console.log(var1);
} else {
console.log(var2);
}
}, frequency );
You want to use setInterval so that the interval is consistent and there is no execution time involved in establishing the time for the next async call.
You can pass in an object reference to control scope and also track the boolean and flip it:
setInterval(function(a){
a.bool = !a.bool
if(!a.bool){
console.log( a.var1)
return
}
console.log(a.var2)
}, 3000, {
bool : true,
var1 : 'value',
var2 : 'other value'
})
You could use setTimeout with two functions that call each other:
var var1 = 'foo';
var var2 = 'bar';
const log1 = () => {
console.log(var1);
setTimeout(log2, 30000)
}
const log2 = () => {
console.log(var2);
setTimeout(log1, 30000)
}
log1();
Here's a more generic approach: For a given list of values - it'll print the provided values in a cycle forever, and will wait for intervalMs between every print
/**
*
* #param {Array} values - collection of values to log
* #param {Number} intervalMs - the log interval
*/
function logValuesCyclicForever(values, intervalMs = 30000) {
let index = 0;
return setInterval(() => {
console.log(values[index]);
index = (index + 1) % values.length; // sets the location back to 0 when the last element is printed.
}, intervalMs);
}
var var1 = 'foo';
var var2 = 'bar';
logValuesCyclicForever([var1, var2]); // for your use case

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

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

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);
}

Timed loop, 10 second between

I currently got this:
var xnumLow = 3000;
var xnumHigh = 4900;
var ynumLow = 9969;
var ynumHigh = 13900;
var ts = Math.round((new Date()).getTime() / 1000);
for (y=ynumLow; y<ynumLow; y++)
{
for(x=xnumLow; x<xnumHigh; x++)
{
$('#box').append(y + " - " + x);
}
}
Now I would like it to append new whole y "row" every 10 seconds, so they all dont append all in once.
The y "row" is the outer for() loop
How can I do this?
I got:
var refreshId = setInterval(function(){ (...) }, 10000);
But I don't know where to merge this with the above code, in order to work correct.
(function () {
var xnumLow = 3000,
xnumHigh = 4900,
ynumLow = 9969,
ynumHigh = 13900,
currentY = ynumLow,
delay = 500,
displayData = function () {
var out = [],
x;
for (x=xnumLow; x<xnumHigh; x++) {
out.push( currentY + "-" + x );
}
console.log(out.join(",")); //do the append here
currentY++;
if (currentY<ynumHigh) {
window.setTimeout(displayData,delay);
}
};
displayData()
})();
setInterval(function () {
// code that appends a box
}, 10000);
https://developer.mozilla.org/en-US/docs/DOM/window.setInterval
var y = ynumLow;
function addRow()
{
for (x = xnumLow; x < xnumHigh; x++) {
$('#box').append(y + " - " + x);
}
if (y++ < ynumHigh)
refreshId = setTimeout(addRow, 10000);
}
addRow();
edited as Pete suggested for clarity
I would do it something like this:
var xnumLow = 3000;
var xnumHigh = 4900;
var ynumLow = 9969;
var ynumHigh = 13900;
var x, y = ynumLow; //don't forget to declare your variables!
var ts = Math.round((new Date()).getTime() / 1000);
(function addYRow() { //Create a function that adds the X elements
for(x=xnumLow; x<xnumHigh; x++)
{
$('#box').append(y + " - " + x);
}
y++; //don't forget to increment y
if(y < ynumHigh) { //only re-call if we aren't done yet
setTimeout(addYRow, 10000); //Recall the function every 10 seconds.
}
}());
Looking at some of the other answers, it's important to realize that you don't want to set up a bunch of things to happen 10 seconds from a given point (which is what happens if you do a loop calling setTimeout(). Instead, I assume you want to add a row, then wait 10 seconds, then add another row. This can only be achieved by adding a row (usiny, in my case, the addYRow() function), then delaying 10 seconds before re-calling the add-a-row function.
Column Delay:
In response to the question about how to do a 500ms delay in the x row, that's a little tricky, but not too bad. You just have to nest things one more time:
var y = ynumLow; //don't forget to declare your variables!
var ts = Math.round((new Date()).getTime() / 1000);
(function addYRow() { //Create a function that adds the X elements
var x = xnumLow;
(function addXCol() { //Create a function that adds each X element
$('#box').append(y + " - " + x);
x++;
if(x < xnumHigh) { //if x is not done, call addXCol 500ms later
setTimeout(addXCol, 500);
} else {
y++;
if(y < ynumHigh) { //If x is done but y isn't, call addYRow 10 seconds later
setTimeout(addYRow, 10000); //Recall the function every 10 seconds.
}
}
}());
}());
Note that if you want to delay the start of the column/row addition (e.g., if you want to put a 500ms delay between when a row is added and when the first column is added, you'll need to adjust the addXCol() expression creation to look like this:
setTimeout(function addXCol() { //Create a function that adds each X element
//...
}, 500);
This will put that initial delay in. Hope that helps.
Something like this?
var refreshId = setInterval(function(){
$('#box').append(++y + " - " + x);
}, 10000);

Looping over contents of a JSON without reloading the page

I have a JSON array(?) of pairs of every state and a value associated with that state, it looks like the following below:
var states = [{"STATE":"AL","AMOUNT":"6"}, {"STATE":"AK","AMOUNT":"3"}]
I need the page to shuffle through them without reloading the page
"AL 6" [wait x seconds] then "AK 3" [wait x seconds] then etc...
I need this to run continuously.
I never use any of these languages but was told that they were my best bet.
Could someone give me some guidance on this please.
Thank you in advance.
Here's a jsfiddle with setInterval execting a function that alternates between each state and displays it in a div:
http://jsfiddle.net/WD5Qj/1/
var states = '[{"STATE":"AL","AMOUNT":"6"}, {"STATE":"AK","AMOUNT":"3"}]';
json = jQuery.parseJSON(states);
var i = 0;
var cycle = function(){
$("#state").html(json[i].STATE + json[i].AMOUNT);
i = (i+1)%json.length;
}
var loop = setInterval(cycle, 500);
Alright, you'd need a function that does the rotation through the array, and a variable for keeping the current state (in both meanings of the word):
var stateIndex = 0;
function rotate() {
stateIndex++;
if(stateIndex >= states.length)
stateIndex = 0;
displayState(states[stateIndex]);
}
And you'd need an interval to perform the rotation:
var stateRotation = window.setInterval(rotate, 3000); // 3000ms = 3 sec
The stateRotation variable is an identifier of your interval. You may use that if you ever want to stop: window.clearInterval(stateRotation);
Now, the above code anticipates a function displayState which takes a state object and displays it. How that would look depends entirely on how you want your state to displayed. In its simplest form, something like this:
function displayState(state) {
$('#state-name').html(state.STATE);
$('#state-amount').html(state.AMOUNT);
}
As per your description, it might perhaps be something more like
$('#state-text').html(state.STATE + ' ' + state.AMOUNT);
var states = [{"STATE":"AL","AMOUNT":"6"}, {"STATE":"AK","AMOUNT":"3"}];
var i = 0;
setInterval(function(){
var array_index = i % states.length;
$('#state').html( states[ array_index ]['STATE'] );
$('#state').html( states[ array_index ]['AMOUNT'] );
i++;
}, 2000);
Here's a fiddle.
function displayNextItem(index){
if (index === states.length)
displayNextItem(0);
$("#someDiv").text(states[index]["STATE"] + " " + states[index]["AMOUNT"]);
setTimeout(function() { displayNextItem(index + 1); }, 1000);
}
And then
displayNextItem(0);
var i = 0, l = states.length, timer, intervalLength = 5000;
timer = setInterval(function(){
if(i >= l){
clearInterval(timer);
}else{
alert(states[i++].STATE);
}
},intervalLength);
This implementation is waiting the AMOUNT number of seconds. If you want constant number of seconds then other answers are better :).
JavaScript:
var states = [{"STATE":"AL","AMOUNT":"6"}, {"STATE":"AK","AMOUNT":"3"}];
function iterate(index) {
var time = states[index].AMOUNT;
// replace the text with new one
$("#output").text(states[index].STATE + " " + time);
setTimeout(function() {
var next = (index + 1) % states.length;
iterate(next);
}, time * 1000);
}
iterate(0);
HERE is the code.

Categories