I'm attempting to nest a setinterval loop inside of a while. The goal is to allow for a certain boolean variable to trigger the setinterval until another condition is true, then stop the iteration. Here is a portion of my code
while (checkTime) {
const checkTime = () => {
machineTime = new Date() - 0;
console.log(machineTime);
if (inputDate <= machineTime && inputDate != null && machineTime != null) {
console.log("Match found");
checkTime = false;
}
};
setInterval(checkTime, 1000);
}
I'm assuming this isn't the right way to what I'm trying to do. Can anyone give me a suggestion on a better way to achieve my goal? Thanks
You don't need a while loop to do that. Just use clearInterval to stop the loop once your condition is met.
let interval;
const checkTime = () => {
machineTime = new Date() - 0;
console.log(machineTime);
if (inputDate <= machineTime && inputDate != null && machineTime != null) {
console.log("Match found");
// This will stop the loop.
clearInterval(interval);
}
};
interval = setInterval(checkTime, 1000);
Related
I was planning to get a data from the server every minute. However, if I run this code, this function is being called repeatedly. On the other hand, if I added date.getMilliseconds == 0 in the condition, it won't process any results.
Do you have any suggestions on how to run the function once every 1 minute?
async update() {
var date = new Date();
if (date.getSeconds() == 0) {
var newdata = await getData(1);
array.shift();
array.push(newdata);
}
}
Since it looks like you don't have fine control over when update is called, one option would be to set a boolean to true every time getSeconds() === 0 (set it to false otherwise), and then only run the real code when the flag is false and getSeconds() === 0:
let hasRun = false;
// ...
async update() {
var date = new Date();
const secs = date.getSeconds();
if (secs !== 0) {
hasRun = false;
} else if (secs === 0 && hasRun === false) {
hasRun = true;
// your code
var newdata = await getData(1);
array.shift();
array.push(newdata);
}
}
An alternative that might require less resources due to not creating Dates every frame would be to have a separate function that toggles the boolean, set with a setInterval that runs every 60 seconds, no Dates involved:
let hasRun = false;
setInterval(() => hasRun = false, 60000);
async update() {
if (hasRun) return;
hasRun = true;
// your code
}
(of course, you could also try setInterval(update, 60000) if the framework allows it)
So I'm trying to make a loop that does something and then when it is finished set a var to false then move to the next loop (or otherwise exit and end the loop). Code:
var loop = true;
while (loop = true)
{
console.log("whatevers");
loop = false;
}
while (loop = false)
{
console.log("meh");
//continue endProgram;
}
So what am I doing wrong here?
= is just assignment, where == or === is for comparisons. Assignment of a variable is evaluated as the expression after the assignment (see #Oka comment). For example: (loop = true => true while loop = false => false) Use == or === instead:
var loop = true;
while (loop == true)
{
console.log("whatevers");
loop = false;
}
while (loop == false)
{
console.log("meh");
//continue endProgram;
}
Try this way
-------------------------------------------------------------------
var loop = true;
while (loop)
{
console.log("whatevers");
loop = false;
}
while (!loop)
{
console.log("meh");
//continue endProgram;
}
while(loop) is the same with while(loop == true )..but loop = true means that you set variable loop equal to true.So try this:
var loop = true;
while (loop)
{
console.log("whatevers");
loop = false;
}
while (!loop)
{
console.log("meh");
}
I have a for loop outside of these two big if´s. My problem seems to be that the second function seems to fire off with a short delay. Should´t First function be done and then second will run?
Can´t figure the problem out why second start before first one is finished. When second function fires aswell it will increase the orignal number from zero to 60.
if(activeSlideBoolean && activeSlide < i){
step = 0;
div[activeSlide].className = 'slide left';
animateHalfLeft(activeSlide);
function animateHalfLeft(activeSlide){
if(step < -60){
return;
}
div[activeSlide].style.left = step+'em';
step -= 6;
setTimeout (function(){ animateHalfLeft(activeSlide);},100);
}
activeSlideBoolean = false;
}
if((activeSlideBoolean === false) && (RestOfSlides)){
step = 60;
animateTotalLeft(RestOfSlides);
function animateTotalLeft(RestOfSlides){
f(step < -60){
return;
}
div[RestOfSlides].style.left = step+'em';
step -= 6;
setTimeout (function(){ animateTotalLeft(RestOfSlides);},100);
}
}
Your function animateHalfLeft and animateTotalLeft are exactly the same except for one thing the argument activeSlide and RestOfSlides.
I suggest first to create a separate function :
function animateToLeft(whatToSlide){
if(step < -60){
return;
}
div[whatToSlide].style.left = step+'em';
step -= 6;
setTimeout (function(){ animateToLeft(whatToSlide);},100);
}
}
But the function is still finishing before setTimeout ends (or even starts).
Javascript is a functional language. Use it :
function animateToLeft(whatToSlide, step, callback){
if(step < -60){
if (typeof callback === 'function') {
callback();
}
return;
}
div[whatToSlide].style.left = step+'em';
step -= 6;
setTimeout (function(){
animateToLeft(whatToSlide , step, callback);
},100);
}
}
if(activeSlideBoolean && activeSlide < i){
var isStarted = false;
animateToLeft(activeSlide, 0, function() {
if (isStarted) {
return;
}
isStarted = true;
if (RestOfSlides) {
animateToLeft(RestOfSlides, 60, null);
// Finishing order 3
}
});
// Finishing order 1
}
if(activeSlideBoolean === false && RestOfSlides){
animateToLeft(RestOfSlides, 60, null);
// finishing order 2
}
I don't know if it works for you (don't copy/paste idiotly) but for me, it's a good start.
I am trying to create a page which needs to preform lots of loops. Using a while/for loops cause the page to hang until the loop completes and it is possible in this case that the loop could be running for hours. I have also tried using setTimeout, but that hits a recursion limit. How do I prevent the page from reaching a recursion limit?
var looper = {
characters: 'abcdefghijklmnopqrstuvwxyz',
current: [0],
target: '',
max: 25,
setHash: function(hash) {
this.target = hash;
this.max = this.characters.length;
},
getString: function() {
string = '';
for (letter in this.current) {
string += this.characters[this.current[letter]];
}
return string;
},
hash: function() {
return Sha1.hash(this.getString());
},
increment: function() {
this.current[0] += 1;
if (this.current[0] > this.max) {
if (this.current.length == 1) {
this.current = [0, 0];
} else {
this.current[1] += 1;
this.current[0] = 0;
}
}
if (this.current[1] > this.max) {
if (this.current.length == 2) {
this.current[2] == 0;
} else {
this.current[3] += 1;
this.current[2] = 0;
}
}
},
loop: function() {
if (this.hash() == this.target) {
alert(this.getString());
} else {
this.increment();
setTimeout(this.loop(), 1);
}
}
}
setInterval is the usual way, but you could also try web workers, which would be a more straightforward refactoring of your code than setInterval but would only work on HTML5 browsers.
http://dev.w3.org/html5/workers/
Your setTimeout is not doing what you think it's doing. Here's what it's doing:
It encounters this statement:
setTimeout(this.loop(), 1);
It evaluates the first argument to setTimeout, this.loop(). It calls loop right there; it does not wait for a millisecond as you likely expected.
It calls setTimeout like this:
setTimeout(undefined, 1);
In theory, anyway. In reality, the second step never completes; it recurses indefinitely. What you need to do is pass a reference to the function rather than the returned value of the function:
setTimeout(this.loop, 1);
However, then this will be window on the next loop, not looper. Bind it, instead:
setTimeout(this.loop.bind(this), 1);
setInterval might work. It calls a function every certain amount of milliseconds.
For Example
myInterval = setInterval(myFunction,5000);
That will call your function (myFunction) every 5 seconds.
why not have a loop checker using setInterval?
var loopWorking = false;
function looper(){
loopWorking = true;
//Do stuff
loopWorking = false;
}
function checkLooper()
{
if(loopWorking == false)
looper();
}
setInterval(checkLooper, 100); //every 100ms or lower. Can reduce down to 1ms
If you want to avoid recursion then don't call this.loop() from inside of this.loop(). Instead use window.setInterval() to call the loop repeatedly.
I had to hand-code continuation passing style in google-code prettify.
Basically I turned
for (var i = 0, n = arr.length; i < n; ++i) {
processItem(i);
}
done();
into
var i = 0, n = arr.length;
function work() {
var t0 = +new Date;
while (i < n) {
processItem(i);
++i;
if (new Date - t0 > 100) {
setTimeout(work, 250);
return;
}
}
done();
}
work();
which doesn't hit any recursion limit since there are no recursive function calls.
Simple question here that I can't seem to find an answer for: Once a setTimeout is set, is there any way to see if it's still, well, set?
if (!Timer)
{
Timer = setTimeout(DoThis,60000);
}
From what I can tell, when you clearTimeout, the variable remains at its last value. A console.log I just looked at shows Timer as being '12', no matter if the timeout has been set or cleared. Do I have to null out the variable as well, or use some other variable as a boolean saying, yes, I have set this timer? Surely there's a way to just check to see if the timeout is still running... right? I don't need to know how long is left, just if it's still running.
What I do is:
var timer = null;
if (timer != null) {
window.clearTimeout(timer);
timer = null;
}
else {
timer = window.setTimeout(yourFunction, 0);
}
There isn't anyway to interact with the timer except to start it or stop it. I typically null the timer variable in the timeout handler rather than use a flag to indicate that the timer isn't running. There's a nice description on W3Schools about how the timer works. In their example they use a flag variable.
The value you are seeing is a handle to the current timer, which is used when you clear (stop) it.
There is no need to check for an existing timer, just execute clearTimeout before starting the timer.
var timer;
//..
var startTimer = function() {
clearTimeout(timer);
timer = setTimeout(DoThis, 6000);
}
This will clear any timer before starting a new instance.
Set another variable Timer_Started = true with your timer. And also change the variable to false when the timer function is called:
// set 'Timer_Started' when you setTimeout
var Timer_Started = true;
var Timer = setTimeout(DoThis,60000);
function DoThis(){
// function DoThis actions
//note that timer is done.
Timer_Started = false;
}
function Check_If_My_Timer_Is_Done(){
if(Timer_Started){
alert("The timer must still be running.");
}else{
alert("The timer is DONE.");
}
}
I know this is a necroposting but i think still people are looking for this.
This is what i use:
3 variables:
t for milliseconds since.. in Date Object for next target
timerSys for the actual interval
seconds threshold for milliseconds has been set
next i have a function timer with 1 variable the function checks if variable is truly, if so he check if timer is already running and if this is the case than fills the global vars , if not truly, falsely, clears the interval and set global var timerSys to false;
var t, timerSys, seconds;
function timer(s) {
if (s && typeof s === "number") {
if (typeof timerSys === "boolean" || typeof timerSys === "undefined") {
timerSys = setInterval(function() {
sys();
}, s);
t = new Date().setMilliseconds(s);
seconds = s;
}
} else {
clearInterval(timerSys);
timerSys = false;
}
return ((!timerSys) ? "0" : t)
}
function sys() {
t = new Date().setMilliseconds(seconds);
}
Example I
Now you can add a line to sys function:
function sys() {
t = new Date().setMilliseconds(seconds);
console.log("Next execution: " + new Date(t));
//this is also the place where you put functions & code needed to happen when interval is triggerd
}
And execute :
timer(5000);
Every 5 seconds in console:
//output:: Next execution: Sun May 08 2016 11:01:05 GMT+0200 (Romance (zomertijd))
Example II
function sys() {
t = new Date().setMilliseconds(seconds);
console.log("Next execution: " + seconds/1000 + " seconds");
}
$(function() {
timer(5000);
});
Every 5 seconds in console:
//output:: Next execution: 5 seconds
Example III
var t, timerSys, seconds;
function timer(s) {
if (s && typeof s === "number") {
if (typeof timerSys === "boolean" || typeof timerSys === "undefined") {
timerSys = setInterval(function() {
sys();
}, s);
t = new Date().setMilliseconds(s);
seconds = s;
}
} else {
clearInterval(timerSys);
timerSys = false;
}
return ((!timerSys) ? "0" : t)
}
function sys() {
t = new Date().setMilliseconds(seconds);
console.log("Next execution: " + seconds / 1000 + " seconds");
}
$(function() {
timer(5000);
$("button").on("click", function() {
$("span").text(t - new Date());
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Freebeer</button>
<span></span>
Note this way you can go below 0
I usually nullify the timer:
var alarm = setTimeout(wakeUpOneHourLater, 3600000);
function wakeUpOneHourLater() {
alarm = null; //stop alarm after sleeping for exactly one hour
}
//...
if (!alarm) {
console.log('Oops, waked up too early...Zzz...');
}
else {
console.log('Slept for at least one hour!');
}