Interval is too slow - javascript

Interval isn't running once per millisecond. The final number only gets to 459 before stopping. Less if there is more than just a line on the interval. On here it doesn't even move through the first thousand. What I want is for it to run once per second to let me know how far an interval is done. So if testNum is at 30, then I know that it's 97% of the way done (2970/3000).
let testNum = 3000
let testInt = setInterval(() => {
testNum--
}, 1)
let testTimeout = setTimeout(() => {
clearInterval(testInt)
console.log('Final Number: ' + testNum)
}, 3000)

From https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval#Parameters:
delay
The time, in milliseconds (thousandths of a second), the timer should delay in between executions of the specified function or code. If this parameter is less than 10, a value of 10 is used.
Have a look at Reasons for delays longer than specified as well.

Related

Is it possible to have a variable interval within a javascript function?

I've been trying without success to set up a way of varying the interval used when incrementing a value by one. It's set to increment every 9 seconds but I'd like the counter to look a little less robotic and instead increment by a repeated variation of numbers, for example, 3 seconds, 7 seconds, 12 seconds, 10 seconds and 13 seconds (the five numbers add up to 45 to ensure an average of 9 seconds is maintained).
I've tried to put these numbers into an array and loop the value of 'interval' through them but I've now realised that value can't be changed within the context of the function once it's started.
Would be super grateful for any advice here. Thanks!
Current code for more 'robotic' count:
let interval = 9000;
let shiftCounter = {{ row.total }};
window.setInterval(function () {
document.getElementById("shiftsCreated").innerHTML = shiftCounter.toLocaleString('en');
shiftCounter = shiftCounter + 1;
}, interval);
You can use setTimeout instead, and every time it completes, call new timeout by choosing random delay or whatever order you want.
let counter = 0;
const intervals = [3, 7, 10, 12]
increment(0);
function increment(timeout) {
setTimeout(() => {
console.log(`Counter: ${counter}.`)
counter++;
increment(intervals[Math.floor(Math.random() * intervals.length)] * 1000)
}, timeout);
}

Creating a Countdown with JavaScript

I am trying to make a Countdown that just log in the terminal the seconds remaining. It should be an interval of 1 second between every log. It has to be as a method of an object. I donĀ“t know if it's because of the scope but somehow it's not working after many trials and code-rewriting.
Anybody can help me with this?
var Countdown = function(seconds) {
this.counter = seconds;
this.start = function() {
setTimeout(
function() {
while (this.counter >= 0) {
console.log(this.counter);
this.counter -= 1;
}
},1000)
}
}
I would use a setInterval() for a simple countdown timer. I would also write my function for the math loop outside of the setInterval and then call on the function within the interval, like the following => setInterval(timerFunction(), 1000). There is no need for a loop when you use the interval, it does the looping each defined time increment as set in your setInterval(). Each time the interval fires, the function will do its thing.
EDIT: added a conditional to see if the interval time has run out.
I have included an example of a simple count down timer in my answer below along with notation inside the code that helps to explain further. Hope this helps.
Also, by terminal, I assume you mean the console? My example displays the setInterval in the console...
let sMin = 2; // amount of minutes you wish to start with
let time = sMin * 60; // format for minutes by multiplying by 60 as we have 60 seconds in each minute
let countdown = setInterval(update, 1000) // set up a setInterval for the countdown function
// create a function that will countdown the seconds
function update() {
// define our minutes using Math.floor(time / 60)
let min = Math.floor(time / 60);
// define our seconds by modulating time with 60, our seconds units
let sec = time % 60;
// tenerary conditional to see if seconds is set to 0 for proper display of formatting as seconds
sec = sec < 10 ? '0' + sec : sec;
// display the countdown timer in time format using the minutes and seconds variables
console.log(`${min}:${sec}`);
// decrement time by one second with each interval as set in the setInterval call `1000`
time--;
// clear the interval if the minutes and seconds are both set to 0
min == 0 && sec == 0 ? clearInterval(countdown) : countdown;
}
Yes it was because of the scope. As you are using this inside setTimeout() it uses the global scope.
var Countdown = function(seconds) {
this.counter = seconds;
this.start = function() {
setTimeout(
function() {
while (this.counter >= 0) {
console.log(this.counter);
this.counter -= 1;
}
}.bind(this),1000)
}
}
I'm using bind to set "this" to current context.
And with reference to your question about timeout, instead of using setTimeout() use setInterval() to achieve your need about log with respect to seconds
function countDown(whileCountingDown, forHowLong, whenFinishedThen){
//error handling begin(for user's understanding)
if(arguments.length<3){return RangeError("ALL three arguments must be used")}
var typeErrors=[]
if(typeof whileCountingDown!="function"){typeErrors.push("whileCountingDown MUST be a function")}
if(typeof forHowLong!="number"){typeErrors.push("forHowLong MUST be a number(and it represents seconds)")}
if(typeof whenFinishedThen!="function"){typeErrors.push("whenFinishedThen MUST be a function")}
if(typeErrors.length>0){return TypeError(`There are ${typeErrors.length} parameters that are incorrect data types\n\n${typeErrors.join('\n')}`)}
//error handling begin(for user's understanding)
//........................................................................................................................
//the part that matters to you once you enter correct stuff
var i=setInterval(()=>{forHowLong--
if(forHowLong<=0){//count finished, determine what happens next
clearInterval(i); whenFinishedThen()
}
else{whileCountingDown(forHowLong)}//do this for each second of countdown
},1000)
}
console.log("The timers in the console and on the html element are 2 DIFFERENT countdowns")
//example use
countDown((m)=>{console.log(`${m} seconds left`)}, 30, ()=>{console.log('Cheers, the countdown is OVER')})
//obviously you can do stuff like edit randomHTML-Element.innerText for each second of the countdown or anything as you so desire since what i made is kindof flexible
//..........................................................................................................................
//more examples
//now for some fun stuff, we're gonna be editing an html structure, but first, we're going to make a 'timeParse' function to make it look kind of elegant
function timeParse(seconds){
//yup, error handling begin
if(typeof seconds!="number"){return TypeError("The parameter 'seconds' MUST be a number")}
//yup, error handling end
//below is the stuff to look at
var timeArr=[seconds]
if(timeArr[0]>=60){//if seconds >= 1 minute
timeArr.unshift(Math.floor(timeArr[0]/60))
timeArr[1]=timeArr[1]%60
if(timeArr[0]>=60){//if minutes >= 1 hour
timeArr.unshift(Math.floor(timeArr[0]/60))
timeArr[1]=timeArr[1]%60
if(timeArr[0]>=24){//if hours >= 1 day
timeArr.unshift(`${Math.floor(timeArr[0]/24)}d`)
timeArr[1]=timeArr[1]%24
}
}
}
return(timeArr.join`:`)
}
//now for applying countDown to things other than the console
function countDownAgain(){//just something that will show the flexibility of what i made.. im going above and beyond because i wanna look back on my answers as notes on how to do things(also ez copy pasting for future me xD)
countDown(
(s)=>{document.getElementById('toTime').innerText="Second Count "+timeParse(s)},
86401,
()=>{document.getElementById('toTime').innerText="No way you waited that long LOL"}
)
}
countDown(
(s)=>{document.getElementById('toTime').innerText="First Count "+timeParse(s)},
100,
countDownAgain
)
<div style="background-color:red;height:100px;text-align:center;line-height:50px"><h1 id="toTime">Count Down Time :}</h1></div>

setInterval Speed Up | Javascript

I'm trying to gradually depreciate the interval in which the function inside a setinterval function is executed
Here's abstracted code for principle:
var speed = 100;
window.setInterval( speed-= 0.01 , speed);
Am I correct in believing the value for speed is taken once, on the first execution of setInterval and used, instead of being taken at every execution.
If so, how can I get around this? I verified this by setting the interval to 1000 and setting the "speed-=" to 999, and then printing the value for speed.
The value jumped from 1000 to 1 but then kept going down by 999, and even after the value became negative the functions inside setinterval were executed every 1 second.
An example of recursive call of setTimeout with changing interval.
function go() {
var node = document.createElement('div');
node.innerHTML = speed.toFixed(2);
document.body.appendChild(node);
if (speed > 1) {
setTimeout(go, speed);
}
speed *= 0.9;
}
var speed = 100;
go();

Skip a setInterval every X loop?

I have a function that gets triggered every 10 seconds with a setInterval(); loop, and I'd like it to skip a call every 60 seconds. So the function would be executed at 10s, 20s, 30s, 40s and 50s but wouldn't be called at 60s, then gets called at 70s and so on.
Is there any straightforward way to do this, or do I have to tinker with incrementing a variable?
Thanks!
Do like this, use the simple modulo math and a counter.
var count = 0;
var interval = setInterval(function(){
count += 1;
if(count % 6 !== 0) {
// your code
}
}, 10000);

using setinterval method in javascript [duplicate]

I'm having problems on Firefox 15 and Chrome 21 with the following code:
setInterval(function () { console.log('test') }, 300000000000)
On both browsers, the function is run right away repeats very quickly. Sure, that's a big number (representing about 10 years from now), but I wouldn't expect it to be treated as a tiny or negative number. I haven't seen a maximum allowed delay in any documentation. Does anyone know if there's a standard max, or if this is just the browsers being funny?
The interval is stored in a signed 32-bit int (in the tested implementation: V8 in Google Chrome), so the behavior you're seeing is the result of the interval overflowing to a negative number (in which case it behaves as if the interval was 0). Thus, the maximum interval that you can use is 2**31 - 1.
Here's how I determined that this was the case:
setInterval(function(){console.log("hi");}, Math.pow(2,31));
Behaves like the interval is 0.
setInterval(function(){console.log("hi");}, Math.pow(2,31) - 1);
Doesn't fire in the time I was willing to wait.
setInterval(function(){console.log("hi");}, Math.pow(2,33) + 1000);
Behaves like the interval is 1000 (one second). Here, the 2**33 doesn't affect the first 32 bits, so we get just 1000.
The highest possible interval, 2**31-1ms is a little shy of 25 days, so more than enough for anything reasonable.
I can't find any documentation at the moment, but I wouldn't be surprised if the timer value had to fit in a 32-bit signed integer.
I think that the maximum delay is 231-1 which is 2,147,483,647ms. The maximum value of a signed 32 bit integer in ms. If it would be unsigned it would be 232-1 = 4,294,967,295.
Max is 2,147,483,647 (231-1)
Be careful that if you make the number bigger than that, it will run immediately (Imaging that you put a negative value, so the browser will run infinitely loop)
setInterval(()=>console.log('n'),2147483647)
31
setInterval(()=>console.log('y'),2147483648)
38
(1588) y
If you need an interval larger than 2,147,483,647 here's an example in TypeScript that will allow you to set an interval for a max of 458,496,310,632,933,156,516.92 days:
Obviously, I have not tested that this works for that long :D.
export const setLongInterval = (callback: any, timeout: number, ...args: any): Timeout => {
let count = 0;
const MAX_32_BIT_SIGNED = 2147483647;
const maxIterations = timeout / MAX_32_BIT_SIGNED;
const onInterval = () => {
++count;
if (count > maxIterations) {
count = 0;
callback(args);
}
};
return setInterval(onInterval, Math.min(timeout, MAX_32_BIT_SIGNED));
};
export const setLongTimeout = (callback: any, timeout: number, ...args: any): Timeout => {
let count = 0;
let handle: Timeout;
const MAX_32_BIT_SIGNED = 2147483647;
const maxIterations = timeout / MAX_32_BIT_SIGNED;
const onInterval = () => {
++count;
if (count > maxIterations) {
count = 0;
clearInterval(handle);
callback(args);
}
};
handle = setInterval(onInterval, Math.min(timeout, MAX_32_BIT_SIGNED));
return handle;
};
The delay argument is converted to a signed 32-bit integer. This effectively limits delay to 2147483647 ms, since it's specified as a signed integer in the IDL.
It is mentioned in the documentation

Categories