var i=0;
function counter(){
for( i;i<100;i++){
setTimeout(()=>{
console.log(i);
},2000)
}
}
counter();
i want to print i in interval of 2 second but it prints immediately
Each call to print takes only a few microseconds. Why? Because it just calls setTimeout. Executing setTimeout takes only a few microseconds to complete. All the call does is schedule something to take place in the future. So within a few microseconds you have scheduled 10 things to take place at about 2 seconds in the future. All the schedulings happen at about the same time. So all the console logs take place at about the same time, two seconds after you scheduled them.
How can i print in interval of 2 second using for loop?
1
2
3
4
... in 2 second delay through for loop
const printNumbersForEvery2Sec = (n) => {
for (let i = 1; i <= n; i++) {
setTimeout(() => {
console.log(i)
}, i * 2000)
}
}
printNumbersForEvery2Sec(10);
Taken from here
Use setInterval(), like this:
var i=0;
var intervalID;
function printAndIncrement()
{
// Stop interval procedure when "var i" reach to 100.
if (i > 100)
{
clearInterval(intervalID);
return;
}
console.log(i);
i++;
}
intervalID = setInterval(printAndIncrement, 1000);
How can i print in interval of 2 second?
'Drift' due to CPU time is a consideration.
If your use case is running code spaced 2 seconds apart minimum, use setTimeout():
let ctr = 1
const fn = () => {
console.log(ctr++)
setTimeout(fn, 2000) // set the next run
}
setTimeout(fn, 2000) // set 1st run
If your use case is running code spaced 2 seconds apart maximum, use setInterval():
let ctr = 1
const fn = () => console.log(ctr++)
setInterval(fn, 2000)
More on JS CPU Timer drift here: https://johnresig.com/blog/how-javascript-timers-work/
Cheers,
function counter(){
for( let i=0;i<100;i++){
setTimeout(()=>{
console.log(i);
},2000)
}
}counter();
Just change var to let
Related
In my application development, I am using
setInterval(function() {
// some code
// runs here
}, 60000);
I want to execute some code on 1 minute interval and my code may take 2-3 minutes in some cases.
<execute code> - <wait 1 minute> - <execute code> - <wait 1 minute> ......so on
I tried with setInterval function but noticed that setInterval does not wait for inner code to complete. Please suggest how can i achieve this in javascript.
Thanks
A better way may be to recursively call your job function with setTimeout:
setTimeout(function jobThatRunEveryMinute() {
// run code here that may take more than one minute
someExpensiveCodeToRun()
// start another job after someExpensiveCode completes
setTimeout(jobThatRunEveryMinute, 60000);
}, 60000);
Something like this might work for you, but why do you have a function that takes over 1 min to return something?
let callCompleted = true;
setInterval(function() {
if (callCompleted) {
callCompleted = false;
// pass a call back function to update the callCompleted to true
myLongRunningFunction(function() { callCompleted = true } );
// or if `myLongRunningFunction` returns a promise
myLongRunningFunction.then(() => { callCompleted = true } );
}
}, 60000);
// adjust wait time to your liking
const waitTime = 10000
let time = 0
// so you can stop it
const totalTime = 6
function excuteCode() {
time++;
console.log(time); // <=== replace with your inner code
if (time < totalTime) {
setTimeout(() => {
excuteCode()
}, waitTime)
}
}
excuteCode();
n = 0;
var timer = setInterval(function() {
if (n == 0) {
console.log(new Date());
}
// execute some other code here
n++;
if (n == 1000) {
clearInterval(timer);
console.log(new Date());
}
}, 1);
This code executes in about 3-4 seconds, depending on machine and browser maybe. How can I make it execute in exactly 1 second?
Javascript timers in browsers are inaccurate (C would be better for that usage).
However, you get a better averaged accuracy having the delay as high as possible, especially avoiding low values, like 1 ms.
It will be difficult to have 1000 evenly timed calls to a function, within one second. One millisecond being a low value , the simple execution of the triggered function itself (plus the overhead of handling timers) is likely to take a time close to 1 ms (or maybe more)... meaning the JS interpreter calls the function after 1ms, executes the code then set a new 1ms timer. Consequently there is more than 1ms between calls.
The JS interpreter does something like
At t call function <-- this takes
execute function <-- some
at t+x set new 1ms timer <-- time
etc...
However if you can afford to end the process within a timeframe closer to 1 second (than the 3-4 seconds you have now), doing as many as possible 1 ms calls, this is possible.
var n = 0;
var timer= setInterval(function(){
if(n++ == 0) {
console.log(new Date());
}
}, 1);
setTimeout(function() {
clearInterval(timer);
console.log("Got n="+n+" at "+(new Date()));
}, 1000);
This is basically the same program as yours
n is incremented every 1ms
however the end of the process is controlled by another 1-second timer
In Chrome, I get 252 n increments and the two dates are ~1 second apart.
Here is a demonstration of the approach for one timer per iteration. It takes roughly 1 second to do 1000 "iterations" of the same callback. The design is rough as it is only an example.
jsFiddle Demo
//Function to compose the array of timers
function timers(count, callback){
var timers = [];
for(var i = 0; i < count; i++){
timers.push(timer(callback,i));
}
return timers;
};
//Function to compose individual timer
function timer(callback, delay){
return function(){
setTimeout(callback,delay);
};
};
//Usage
console.log("Start:",new Date()); //timestamp
var display = document.querySelector("#display");
var settings = { n : 0 };
display.innerHTML = settings.n;
//Arrange timers and callback
var set = timers(1000,function(){
this.n++;
display.innerHTML = this.n;
if(this.n === 1000) console.log("End:",new Date());
}.bind(settings));
//Execute timers
for(var i = 0; i < set.length; i++){ set[i](); }
<div id="display">
</div>
All browsers handle this differently. In most browsers, especially chrome, the default smallest amount of time possible for a task to execute (as in using an interval or timeout) is 4 milliseconds.
The result of the 4ms window is that your 1000 iterations are being done in about 4 seconds. So, clearly this is longer than the desired 1 second in 1000 iterations.
There is not a desirable (possible?) way to accomplish an exact 1 millisecond iteration in JavaScript when executed in a modern browser. The best bet you would have if space (memory and processing power) were not an issue would be to create a timer for each iteration manually and then execute the entire set of them. This of course has its own issues, such as whether or not each task is even executed at the time it was supposed to.
Try the same script in ECMA Script 6
'use strict';
var n = 0;
var timer = setInterval(() => {
n++;
}, 1);
console.log( new Date() );
setTimeout(() => {
clearInterval(timer);
console.log("Final N Value: "+n+" at "+ (new Date()) );
}, 1000);
I've got this Problem here, that this function is not working and I cant figure out why..
This function should count to 10 (in 10 seconds). For this purpose I'm using a for loop with setTimeout function - duration set to 1000ms.
It should go on and on for what i took the setInterval function.
function timer() {
var time=10;
for(i=0; i<time; i++){
setTimeout(console.log(i+1), 1000);
}
}
setInterval(timer, 10000);
The Problem is, that it isnt working and I dont understand why ... I have found another working solution but would like to know the issue of this one. :)
The reason that nothing appears to happen is the way that you use setTimeout. Instead of providing an event handler you are calling console.log and try to use the return value from that call as event handler.
The closest thing that would at least do something would be to make a function that calls console.log:
setTimeout(function(){ console.log(i+1) }, 1000);
However, you will notice that it will just log the value 11 ten times at once, every ten seconds, indefinitely.
Eventhough the loop counts from 0 to 9, you start a timeout in each iteration that will be triggered one second from when it was created. As all ten timeouts are created at the same time, they will be triggered at the same time. There isn't a separate variable i for each handler, so they will all show the value in the variable at the time that they are triggered, and as the loop has completed before any of them can be called they will all show the final value 10 + 1.
You are using both an interval and timeouts, you should use one or the other.
You can start timeouts in a loop, but then you should only do it once, not in an interval, and you should specify the time from start to when you want it to be triggered:
var time = 10;
for (var i = 1; i <= time; i++){
setTimeout(function() { console.log('tick'); }, 1000 * i);
}
If you want to use the variable in the event handler, then you need to create a copy of the variable for each iteration:
var time = 10;
for (var i = 1; i <= time; i++){
(function(copy){
setTimeout(function() { console.log(copy); }, 1000 * i);
})(i);
}
You can use an interval, but then you don't have a loop, it's the interval that is the loop. Use clearInterval to stop it when you reach the end of the loop:
var i = 1, time = 10, handle;
function timer() {
console.log(i);
i++;
if (i > time) clearInterval(handle);
}
handle = setInterval(timer, 1000);
First, it's not working because setTimeout call is wrong. Even if your setTimeout call worked, there's another issue here. Your code will actually print 11 every 10 seconds.
function timer() {
var time = 10;
for (i = 0; i < time; i++) {
setTimeout(function() {
console.log(i + 1)
}, 1000);
}
}
setInterval(timer, 10000);
Because, you have sequential setTimeout calls to be effected every second and you are forming a closure on the variable i.
You need to take care of the closure and calls must be done after the second has been printed.
function timer() {
var p = Promise.resolve();
for (var i = 0; i < 10; i++) {
p = p.then(closure(i));
}
}
function closure(i) {
return (function () {
return new Promise(function (resolve) {
setTimeout(function () {
document.getElementById('results').innerHTML = (i + 1) + '\n';
resolve();
}, 1000);
})
});
}
timer();
setInterval(timer, 10000);
<pre id="results"></pre>
When I run your code in the Firebug debugger, I see:
TypeError: can't convert console.log(...) to string
I added a comment to your code about that error:
function timer() {
var time=10;
for(i=0; i<time; i++){
// The source of error is the line below
// Type error: setTimeout needs a function as first argument!
setTimeout(console.log(i+1), 1000);
}
}
setInterval(timer, 10000);
A corrected version might be
function timer() {
var time=10;
for(i=0; i<time; i++){
setTimeout(function() { console.log(i+1); }, 1000);
}
}
setInterval(timer, 10000);
However, the above change fixes the type error but not the logic.
You probably wanted to do this:
var counter = 0;
var count = function() {
console.log(++counter);
if (counter >= 10) {
clearInterval(timer);
}
};
var timer = setInterval(count, 1000);
Once the callback function count notices the counter passed the value 10 it will stop the periodic timer whose ID was saved in the variable timer when setting it up.
I have this code:
for (i = 0; i < 3; i++) {
var interval = setInterval(function(){
alert(i);
}, 2000);
}
What I would like to achieve is to have an alert every 2 sec displaying first 0, then 1 and lastly 2.
Instead I have to wait for quite long before I have 3 alerts all displaying the number 3. Where is my code wrong?
Well, there is (yet again) more than one solution to this problem. But, lets first talk why your code doesn't work properly.
Your code:
for (i = 0; i < 3; i++) {
var interval = setInterval(function(){
alert(i);
}, 2000);
}
..basically means that it will assign three setInterval calls to be executed after 2 seconds as fast as the for loop is placing them to the queue. So basically, all your calls runs really fast after 2 seconds, only few milliseconds or less between them. Moreover, setInterval means that it will be called as long as clearInterval is called to the variable it is assigned with. In other words, your code never stops executing the alert, because you are never calling clearInterval. Finally, your alert(i) will always display value of 3, because it is the last value of i when execution moves away from the for loop.
To improve your code, you could remove the for loop entirely and just let setInterval run as long as the value of i is alerted three times; At that point, you just call clearInterval to the value which has handle to setInterval and the job is finished.
Working code:
// value to output
var i = 0,
// starting setInterval and assigning its handle to variable interval,
// it is used to clear the interval when execution should be finished
interval = setInterval(function () {
// alert value of i and increase it by 1
alert(i++);
// if i is equals to 3, no more calls
if(i === 3) {
// clear the interval so method won't be called in the future
clearInterval(interval);
}
}, 2000);
JS FIDDLE EXAMPLE
Cheers, hopefully you learnt something new today.
Without forloop:
var number = 0;
var interval = setInterval(function(){
alert(number);
number++;
if(number === 3) {
clearInterval(interval);
}
}, 2000);
JSFIDDLE
1.1 Without for loop + without initial delay (demo):
var i = 0;
var showAlert = function(){
alert(i);
i++;
if(i < 3){
setTimeout(function(){
showAlert();
}, 2000);
}
};
showAlert();
1.2 Without for loop + with initial delay (demo):
var i = 0;
var showAlert = function(){
if(i < 3){
setTimeout(function(){
alert(i);
i++;
showAlert();
}, 2000);
}
};
showAlert();
2.1 With for loop + without initial delay (demo):
function setAlert(k){
setTimeout(function(){
alert(k);
},k * 2000);
}
for(var i = 0; i < 3; i++) {
setAlert(i);
}
2.2 With for loop + with initial delay (demo):
function setAlert(k){
setTimeout(function(){
alert(k);
},(k + 1) * 2000);
}
for(var i = 0; i < 3; i++) {
setAlert(i);
}
First of all, I would go with setTimout, you know that you want 3 alerts.
Second problem is a bit stranger. You are calling async function, setTimeout/setInterval and referring to the original i of the for loop inside of the setTimeout callback. That will not work because at the time of the timeout invocation the for loop has already finished and i var will be 3. One solution is to wrapp the async function in a self invoking anonymous function with params that you need inside async function. In our case we call it with i.
Solution:
for (i = 0; i < 3; i++) {
(function(i) {
setTimeout(function(){
alert(i);
}, 2000 * i);
})(i);
}
JS fiddle
Can someone let me know where I'm going going? I'm just trying to count down from a given number in the code and print to screen 1, pause for 1 second, print 2, pause for 1 second, print 3, pause for 1 second...
I tried using sleep(1000) but always get a 'sleep undefined' error and when I use the below code the setTimeout(1000) returns "invalid arguement"
var i;
function timer()
{
for (i = 0; i <= 10; i++)
{
setTimeout(1000);
document.write(i);
}
}
timer();
The setTimeout doesn't work like that, it is not the same as sleep in java or any other language
you can use something like
var i = 0;
function timer(){
document.write(i++);
if(i >= 10){
clearInterval(timerId)
}
}
var timerId = setInterval(timer, 1000)
The parameters for setTimeout are (functionToCall, time).
This is because setTimeout (like most functions in JavaScript) is asynchronous: while it waits for one second, it does other stuff in the program. Once the time is up, it comes back and runs the function.
var message = "Hello, World!";
var timer = function timer() {
document.write(message);
};
setInterval(timer, 1000); //will print 'Hello, World!' after one second