If i need to get some new data constanly, i know that best solution is websockets.In that way the server will notify the client when there is new data. But to avoid this just for one scenario, i will need to call some http request on every five seconds.
I am using here counter just for simulation instead calling some http service.
let counter = 0;
setInterval(() => {
console.log(counter);
++counter;
},5000)
I've read that better solution is requestAnimationFrame instead of setInterval.It is more optimised by the browser and also when the tab is not active it is paused. Set interval continues to fire and when the tab is not active which is not good.
How can i call some function in requestAnimationFrame every five seconds ?
To actually only call it every 5 seconds, you'd still need (at least) setTimeout. But with this, something along the following would work:
requestAnimationFrame(function run() {
console.log('do something w/o initial delay');
setTimeout(function () {
console.log('do something w/ initial delay');
requestAnimationFrame(run);
}, 5000);
});
Related
I tried to make a stopwatch in the console, but the message kept on clearing before I had time to read it.
I tried increasing how long the Timeout function would go, but for some reason, it didn't make a difference.
Can somebody help me with making the messages not clear so fast?
setTimeout(function() {
console.log("1");
}, 1000);
setTimeout(function() {
console.clear()
},1099);
setTimeout(function() {
console.log("2");
}, 2000);
setTimeout(function() {
console.clear()
}, 2099);
setTimeout(function() {
console.log("3");
}, 3000);
setTimeout(function() {
console.clear()
}, 3099);
second argument to settimeout represents time in milliseconds. 1000ms = 1seconds. consider this. Maybe you should increase the time it takes to run the console.clear(), base on your code it executes after 2 and 3 seconds.
#Mr.Buscuit, consider using the setInveral function,
let sec = 0;
setInterval(function () {
console.clear();
console.log(sec);
sec++;
}, 1000);
This log a new number to the log every second. Hope this helps.
1- first line of code you tell your browser to execute that function which print on console number "1"
2- second line you tell browser after 99ms (from beginning of timer) NOT 1099ms clear the console
Why 99ms? because All Timer API(Browser API) e.g (setTimeout, setInterval) works at same time, all of these functions that you do, they have a one(only one) timer, hence that means when timer reach at 1000ms, second setTimeout that you determined its timer with 1099ms reached at 1000ms as well (one timer), hence still 99ms remaining from 1099ms
Summary
Imagine there is one big timer is running for all functions, this means if we have 2 setTimeout with time we specified 1000ms (2 function with same time) this is not means after finish first function that need 1000ms, second starts setTimeout timer that will begin from scratch, hence need 1000ms again with total latency 2000ms, No, this is wrong, two functions will work together
very good resource for understand this concept : Async Concept
I am making a Snake game on my webpage using JavaScript and HTML. In this game I want to call a function after regular time intervals. This function will update and print the position of the snake.
For this I am using setTimeOut(my_function,time).
My code looks like this
function my_function(){
// update values
// display snake
setTimeOut(my_function,time)
}
My question is - Will the above code create a lot of function calls on the function stack like a recursive function. I think it will.
Below is how I think I can optimise it.
function empty_function{
}
while(true){
//update values
//display snake
setTimeOut(empty_function,time)
}
Will this method will also create a lot of function calls on the function stack like a recursive function?
Your optimized solution is actually the one that will crash the program, because it keeps the same function running forever. Your first approach is perfectly fine: setTimeout doesn't call the function immediately but schedules it to be run. In the meantime your process can handle other events and start with a new stack when your function is due to be called.
In your infinite while loop your function will never even be called, as there will never be time for the program to check its scheduled task list.
If your interval is frame based (for example, you wish to update your graphics as often as possible) you might be better off with requestAnimationFrame():
function update(timestamp) {
// render your game
// request this function to be run again on the next frame:
window.requestAnimationFrame(update);
}
window.requestAnimationFrame(update);
As you can see it uses the same approach, but is specifically designed to try and match the refresh rate of the users screen freeing you from having to define the interval between render ticks.
You can achieve this more easily by setInterval.Here is an example;
setTimeout(() => {console.log('this will get printed only once after 1000 ms')}, 1000);
setInterval(() => {console.log('this will get printed after every 1000 ms')}, 1000);
setInterval runs a function again and again after given interval of time.
If you want to stop the setInterval function, this is how you can do it;
let myinterval = setInterval(() => {console.log('Print this again and again after 1000 ms')}, 1000);
// Down here i am clearing the 'myInterval' interval using the 'clearInterval' function.
const clear = () => {
console.log('printing stopped');
clearInterval(myinterval);
}
document.getElementById('stop').addEventListener('click', clear);
<button id='stop'>Stop printing</button>
I am working on the initial data pull for a project. It will be cached and further requests will be much less. I am attempting to space out my API requests every 5 seconds to avoid overloading the server and hitting the rate limit per their rules. It does not seem that my setTimeout() function is actually working as desired. I logged time stamps to see and all iterations seem to be happening at the exact same time. I think this somehow due to the asynchronous nature of javascript, but I'm not sure how to remedy it. Any help would be greatly appreciated.
Code Excerpt:
var leagues;
function getLeagues(){
var reqURL = "url";
var data = new XMLHttpRequest();
data.open("GET", reqURL);
data.responseType = "text";
data.send();
// parse data on load
data.onload = function() {
// League IDs
leagues = JSON.parse(data.response)
for (i = 0; i < 5; i++) {
delay(i); // iterate every 5 secs
}
};
}
function delay(i) {
setTimeout(() => {
var d = new Date();
console.log(d.getSeconds())
}, 5000);
}
You call delay to tell JS to do something in 5 seconds.
Then you immediately call delay to tell JS to do something in 5 seconds again.
So 5 seconds later the first delay timeout triggers, then immediately after that the second one triggers.
If you want to space them apart then you need to either:
Call delay the second time in the function that setTimeout calls so the second timer doesn't start under the first one is finished
Multiply your times so the first one is 5 seconds but the second is 10 seconds and so on
Refactor the code to use setInterval instead
setTimeout is a browser API that will guarantees not an exact delay time to execute after but a minimum time to execute a function so it's not related to js.
setTimeout cause the browser to set a timer after x milliseconds, when finished the function you pass will be in the event queue, but it won't necessarily execute, if event queue was completely empty, you are lucky and the function get executed immediately after 5 seconds, otherwise the function have to wait in queue until each function get executed before so we have (5 seconds + some times until the function get in the head of the queue then get executed).
calling setTimeout five times in sequence (using a for loop) with the same time delay will add the same function 5 consequent times in the event queue, all will be executed at the same time because of the same time delay used for all of them. so a solution would be to use different delay time for each function.
I'll suggest the solution for the same problem, because I faced it alot
Callback based solution
repeat(processingRequest, 5, 5000);
function processingRequest(){
console.log('Making request at', new Date().getTime());
}
function repeat(func, howManyTimes, milliSecondsInterval){
if(howManyTimes > 0)
delay(() => {
func();
howManyTimes--;
repeat(func, howManyTimes, milliSecondsInterval);
}, milliSecondsInterval);
}
function delay(func, milliSeconds){
setTimeout(func, milliSeconds);
}
Promise based solution(more preferred)
repeat(processingRequest, 5, 5000);
function processingRequest(){
console.log('Making request at', new Date().getTime());
}
function repeat(func, howManyTimes, milliSeconds){
delay(milliSeconds)
.then(() => {
func();
howManyTimes--;
if(howManyTimes > 0)
repeat(func, howManyTimes, milliSeconds);
});
}
function delay(milliSeconds){
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, milliSeconds);
});
}
using a library like rxjs(providing a repeat and delay) will make things even more simple
https://rxjs-dev.firebaseapp.com/api/operators/repeat
https://rxjs-dev.firebaseapp.com/api/operators/delay
even though not every application need rxjs, but we have to say it give the programmer a great power over clean sync or async operations
[References]
For further knowledge about Browser API & Event queue
Cool talk from Philip Roberts
https://youtu.be/8aGhZQkoFbQ?t=1165
from THE BEST great js resource I've found
https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/async%20%26%20performance/ch1.md
You can use a Promise instead of a timeout. The setTimeout function will wait five seconds and all code will be executed, because it does not block the execution. A promise instead will do that:
async function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
};
You can use the promise inside of an async loop:
async function getLeagues(){
var reqURL = "url";
var data = new XMLHttpRequest();
data.open("GET", reqURL);
data.responseType = "text";
data.send();
// parse data on load
data.onload = function() {
// League IDs
leagues = JSON.parse(data.response)
const delays = [...new Array(5)]; // To have something to loop over
for await (const d of delays) {
await delay(5000);
}
};
}
function delay(i) {
setTimeout(() => {
var d = new Date();
console.log(d.getSeconds())
}, i * 5000);
}
The process of setting up the timeout i.e. the calls to setTimeout() — takes almost no time at all. If a succession of timeout requests is made, the delay value is the same for each one, then once that amount of time has elapsed.. all the timer handlers will be called consecutively rapidly. If you need the handlers to be called at intervals, you can either use setInterval(), which is called exactly like setTimeout() but will fire more than once after repeated delays of 5000, or instead, you can establish the timeouts and multiply the time value by your iteration counter i.e. 'i' in this case. The value of i is multiplied by the original delay value, so calling that 5 times in a loop will result in delays of 5 seconds, 10 seconds, 15 seconds, 20 seconds, and 25 seconds.
I am trying to understand this code:
function setIdle(cb, seconds) {
var timer;
var interval = seconds * 1000;
function refresh() {
clearInterval(timer);
timer = setTimeout(cb, interval);
};
$(document).on('keypress, click', refresh);
refresh();
}
setIdle(function() {
location.href = location.href;
}, 5);
setIdle takes two arguments. Inside its function it has a function refresh that clears a timer on a Timeout function. Now every time when an event happens (click, keypress) refresh() gets called.
and then finally this function gets called passing in another function and and int value (5) which later will be the amount of seconds for the timer. In that other function which later is represented through cb the page will be refreshed (location.href = location.href;).
This causes an automaticpage refresh every 5 seconds.
So now I don't understand if I put an additional function:
setIdle(function() {
console.log('hi');
}, 1);
Why is the second function only called once and not every second like the other one?
setIdle doesn't run the callback function every 5 seconds. It runs it once, 5 seconds after you call setIdle, and if you type or click something the timeout gets pushed back again. So it runs it once, when you've been idle for 5 seconds.
The reason the page refreshes every 5 seconds is because the callback function reloads the page, and reloading the page runs all the Javascript in the page again, so that calls setIdle() again.
But your second use of setIdle doesn't reload the page, so it just logs hi once.
If you want to do something repeatedly every N seconds, use setInterval rather than setTimeout.
BTW, clearInterval should be clearTimeout. In most browser they're currently interchangeable, but there's no guarantee. See Are clearTimeout and clearInterval the same?
Is there any way to call a function periodically in JavaScript?
The setInterval() method, repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. It returns an interval ID which uniquely identifies the interval, so you can remove it later by calling clearInterval().
var intervalId = setInterval(function() {
alert("Interval reached every 5s")
}, 5000);
// You can clear a periodic function by uncommenting:
// clearInterval(intervalId);
See more # setInterval() # MDN Web Docs
Please note that setInterval() is often not the best solution for periodic execution - It really depends on what javascript you're actually calling periodically.
eg. If you use setInterval() with a period of 1000ms and in the periodic function you make an ajax call that occasionally takes 2 seconds to return you will be making another ajax call before the first response gets back. This is usually undesirable.
Many libraries have periodic methods that protect against the pitfalls of using setInterval naively such as the Prototype example given by Nelson.
To achieve more robust periodic execution with a function that has a jQuery ajax call in it, consider something like this:
function myPeriodicMethod() {
$.ajax({
url: ...,
success: function(data) {
...
},
complete: function() {
// schedule the next request *only* when the current one is complete:
setTimeout(myPeriodicMethod, 1000);
}
});
}
// schedule the first invocation:
setTimeout(myPeriodicMethod, 1000);
Another approach is to use setTimeout but track elapsed time in a variable and then set the timeout delay on each invocation dynamically to execute a function as close to the desired interval as possible but never faster than you can get responses back.
Everyone has a setTimeout/setInterval solution already. I think that it is important to note that you can pass functions to setInterval, not just strings. Its actually probably a little "safer" to pass real functions instead of strings that will be "evaled" to those functions.
// example 1
function test() {
alert('called');
}
var interval = setInterval(test, 10000);
Or:
// example 2
var counter = 0;
var interval = setInterval(function() { alert("#"+counter++); }, 5000);
Old question but..
I also needed a periodical task runner and wrote TaskTimer. This is also useful when you need to run multiple tasks on different intervals.
// Timer with 1000ms (1 second) base interval resolution.
const timer = new TaskTimer(1000);
// Add task(s) based on tick intervals.
timer.add({
id: 'job1', // unique id of the task
tickInterval: 5, // run every 5 ticks (5 x interval = 5000 ms)
totalRuns: 10, // run 10 times only. (set to 0 for unlimited times)
callback(task) {
// code to be executed on each run
console.log(task.id + ' task has run ' + task.currentRuns + ' times.');
}
});
// Start the timer
timer.start();
TaskTimer works both in browser and Node. See documentation for all features.
You will want to have a look at setInterval() and setTimeout().
Here is a decent tutorial article.
yes - take a look at setInterval and setTimeout for executing code at certain times. setInterval would be the one to use to execute code periodically.
See a demo and answer here for usage
Since you want the function to be executed periodically, use setInterval
function test() {
alert('called!');
}
var id = setInterval('test();', 10000); //call test every 10 seconds.
function stop() { // call this to stop your interval.
clearInterval(id);
}
The native way is indeed setInterval()/clearInterval(), but if you are already using the Prototype library you can take advantage of PeriodicalExecutor:
new PeriodicalUpdator(myEvent, seconds);
This prevents overlapping calls. From http://www.prototypejs.org/api/periodicalExecuter:
"it shields you against multiple parallel executions of the callback function, should it take longer than the given interval to execute (it maintains an internal “running” flag, which is shielded against exceptions in the callback function). This is especially useful if you use one to interact with the user at given intervals (e.g. use a prompt or confirm call): this will avoid multiple message boxes all waiting to be actioned."