I have the following statement
if (!this.customMsg) {
this.customMsg = setInterval(() => {
// doSomething();
}, 2000);
}
I want to do something like this;
this.customMsg = !this.customMsg && setInterval(() => {
// doSomething();
}, 2000);
The above way doesn't work, what am i doing wrong.
You can try this
this.customMsg || (this.customMsg = setInterval(function() {
}, 2000));
Related
Created a timer, I want to be able to stop the interval once the seconds drop down to 0.
This is what I got so far
useEffect(() => {
if (alarm?.timerOn && alarm?.seconds === 0) {
console.log('stop?')
clearInterval(alarmTimer)
console.log('stop? below clear interval')
}
}, [alarm?.seconds])
The console logs appear exactly at 0 just like I want it but the clear interval doesn't do anything? I have declared the alarmTimer like this let alarmTimer: any outside the useEffect
How the start timer works
alarmTimer = setInterval(() => {
if (alarm!.seconds > 0) {
dispatch!({ type: 'DECREMENT_SECONDS' })
}
}, 1000)
So instead of clearing at 0 it carrys on and goes down to -1,-2,-3 etc
Decided to use Ref instead like this and it seems to have worked!
const intervalRef = useRef(null)
intervalRef.current = setInterval(() => {
if (alarm!.seconds > 0) {
dispatch!({ type: 'DECREMENT_SECONDS' })
}
}, 1000)
useEffect(() => {
if (alarm?.timerOn && alarm?.seconds === 0) {
clearInterval(intervalRef.current)
intervalRef.current = null
}
}, [alarm?.seconds])
I need to exit from a running interval if the conditions are correct:
var refreshId = setInterval(function() {
var properID = CheckReload();
if (properID > 0) {
<--- exit from the loop--->
}
}, 10000);
Use clearInterval:
var refreshId = setInterval(function() {
var properID = CheckReload();
if (properID > 0) {
clearInterval(refreshId);
}
}, 10000);
Pass the value of setInterval to clearInterval.
const interval = setInterval(() => {
clearInterval(interval);
}, 1000)
Demo
The timer is decremented every second, until reaching 0.
let secondsRemaining = 10
const interval = setInterval(() => {
// just for presentation
document.querySelector('p').innerHTML = secondsRemaining
// time is up
if (secondsRemaining === 0) {
clearInterval(interval);
}
secondsRemaining--;
}, 1000);
<p></p>
Updated for ES6
You can scope the variable to avoid polluting the namespace:
const CheckReload = (() => {
let counter = - 5;
return () => {
counter++;
return counter;
};
})();
{
const refreshId = setInterval(
() => {
const properID = CheckReload();
console.log(properID);
if (properID > 0) {
clearInterval(refreshId);
}
},
100
);
}
I have a function as below:
function foo(args1, args2, retry)
{
if (retry <= 0)
return false;
var isDone = callAnotherFunction(args1, args2);
if(!isDone) {
setInterval(function () {
foo(args1, args2, retry-1);
},
2000);
}
else
return true;
}
So I am not sure if the above implementation is correct. But I need to use this function in another function. And use the above function in an if block to decide if the other statement needs to be executed. Below is the usage of the above function.
function useIt(args1, args2)
{
// Other code
let store = function() {
if(!foo(args1, args2, 5)) {
cleanStorage(args1, args2);
return;
}
}
So the problem is in function useIt(), cleanStorage() does not wait for foo() to be executed if I am using setInterval or setTimeOut. So how do I need to implement the function foo() ? Kindly help me.
consider using promises
foo can be rewritten like this (I've replace setInterval with setTimeout):
function foo(args1, args2, retry) {
return new Promise(function (resolve, reject) {
if (retry <= 0)
reject();
var isDone = callAnotherFunction(args1, args2);
if (!isDone) {
setTimeout(function () {
resolve(foo(args1, args2, retry - 1));
}, 2000);
}
else
resolve(true);
})
}
and then use it like this:
function useIt(args1, args2) {
// Other code
let store = function () {
foo(args1, args2, 5).then(function () {
cleanStorage(args1, args2);
});
}
}
You should use Promises to do this
Something like this:
function foo(args1, args2, retry)
{
return new Promise(function(resolve, reject) {
if (retry <= 0)
reject();
var isDone = callAnotherFunction(args1, args2);
if(!isDone) {
setInterval(function () {
retry = retry - 1;
isDone = callAnotherFunction(args1, args2);
if (isDone)
resolve();
},
2000);
}
else
resolve();
}
}
function useIt(args1, args2)
{
// Other code
let store = function() {
foo(args1, args2, 5).then(result => {
cleanStorage(args1, args2);
return;
}
}
}
This question already has answers here:
How do I add a delay in a JavaScript loop?
(32 answers)
Closed 9 years ago.
I'm trying to get this loop to work in javascript so it opens and closes an accordion at different intervals.... It only runs the loop once and stops. I'm banging my head against the wall as to why?
var i;
i = 0;
while (i < 999) {
setTimeout((function() {
return $("#money-slide").collapse("show");
}), 0);
setTimeout((function() {
return $("#money-slide").collapse("hide");
}), 4000);
setTimeout((function() {
return $("#collaboration-slide").collapse("show");
}), 4000);
setTimeout((function() {
return $("#collaboration-slide").collapse("hide");
}), 8000);
setTimeout((function() {
return $("#efficiency-slide").collapse("show");
}), 8000);
setTimeout((function() {
return $("#efficiency-slide").collapse("hide");
}), 12000);
setTimeout((function() {
return $("#communication-slide").collapse("show");
}), 12000);
setTimeout((function() {
return $("#communication-slide").collapse("hide");
}), 16000);
i++;
}
Use
setInterval
instead of
setTimeout
Also setTimeout ot setIterval are async , so returning anything from it won't do anything.
Try this
var i = 0;
var timer1, timer2, timew3, timer4, timer5, timer6, timer7, timer8;
setAnimationIntervals();
i = 0;
function setAnimationIntervals() {
timer1 = setInterval((function () {
$("#money-slide").collapse("show");
}), 0);
timer2 = setInterval((function () {
$("#money-slide").collapse("hide");
}), 4000);
timer3 = setInterval((function () {
$("#collaboration-slide").collapse("show");
}), 4000);
timer4 = setInterval((function () {
return $("#collaboration-slide").collapse("hide");
}), 8000);
timer5 = setInterval((function () {
$("#efficiency-slide").collapse("show");
}), 8000);
timer6 = setInterval((function () {
$("#efficiency-slide").collapse("hide");
}), 12000);
timer7 = setInterval((function () {
$("#communication-slide").collapse("show");
}), 12000);
timer8 = setInterval((function () {
$("#communication-slide").collapse("hide");
i++;
if (i === 999) {
clearAnimationIntervals();
}
}), 16000);
}
function clearAnimationIntervals {
clearInterval(timer1);
clearInterval(timer2);
clearInterval(timer3);
clearInterval(timer4);
clearInterval(timer5);
clearInterval(timer6);
clearInterval(timer7);
clearInterval(timer8);
}
Instead of setting your time-outs when the previous time-out has ended, you set all 999 time outs at once.
You need to set a new time-out in the time-out function. Or better use setInterval
the reason why it does it once is because you schedule so many timeouts in a loop, and then they all run simultaneously, and when each one is executed, it just stops. You would need to create another timeout from the timeout callback, or use setInterval.
Something along the lines of (not tested):
var money_slide_visible = false;
var money_slide_handler = function () {
$("#money-slide").collapse(money_slide_visible ? 'hide' : 'show');
money_slide_visible = !money_slide_visible;
setInterval(money_slide_handler, 4000);
};
money_slide_handler();
So, I've got this type of situation, but I only want to "Do something" if the user "mouseleave(s)" for more than x amount of time, say one second. How should I implement that?
$("#someElement, #someOtherElement").mouseleave(function() {
// Do something.
});
Later I added:
$('.popover3-test').popover({
placement:'bottom',
template: $('.popover2'),
trigger: 'manual',
}).mouseenter(function(e) {
$(this).popover('show');
$(".popover3-test, .popover2").each(function() {
var t = null;
$(this)
.mouseleave(function() {
t = setTimeout(function() {
$('.popover2').hide();
}, 1000); // Or however many milliseconds
})
.mouseenter(function() {
if(t !== null)
clearTimeout(t);
})
;
});
});
setTimeout should do the trick:
$("#someElement, #someOtherElement").each(function() {
var t = null;
$(this)
.mouseleave(function() {
t = setTimeout(function() {
// Do something.
}, 1000); // Or however many milliseconds
})
.mouseenter(function() {
if(t !== null) {
clearTimeout(t);
t = null;
}
})
;
});
EDIT: If you want it to work on either, just remove the .each:
var t = null;
$("#someElement, #someOtherElement")
.mouseleave(function() {
t = setTimeout(function() {
// Do something.
}, 1000); // Or however many milliseconds
})
.mouseenter(function() {
if(t !== null) {
clearTimeout(t);
t = null;
}
})
;
$("#someElement, #someOtherElement").bind('mouseenter mouseleave', (function() {
var timer;
return function (e) {
if(e.type === 'mouseleave') {
timer = setTimeout(function () {
//do something
}, 1000);
} else {
clearTimeout(timer);
}
};
}()));
EDIT - usable on multiple elements
$("#someElement, #someOtherElement").bind('mouseenter mouseleave', function (e) {
var timer = $(this).data('timer');
if(e.type === 'mouseleave') {
timer = setTimeout(function () {
//do something
}, 1000);
} else {
clearTimeout(timer);
}
$(this).data('timer', timer);
};
});
this might not work as is, but gives you some ideas...
var elapsed = 0;
var timer = setInterval(function(){
elapsed += 20;
if( elapsed >= 1000 ) {
doSomething();
clearInterval(timer);
}
}, 20 );
$('#some').mouseleave(timer);
$('#some').mouseenter(function(){clearInterval(timer);elapsed=0;});