Pause JS function from another function - javascript

Is there any way I can pause the below set of delayed functions from another function? I want to pause everything for 10 seconds by executing another function.
What I need is something like:
function pause(){
pause sleepLoop() for 10 seconds
}
If it is not possible to pause the below execution, can I kill it?
function game() {
sleepLoop();
}
function sleepLoop() {
loop...
setTimeout('gameActions()',5000);
}
function gameActions() {
actions...
sleepLoop();
}

Store the timer in a variable. Then you can stop it with clearTimeout, and restart it after 10 seconds:
function game() {
sleepLoop();
}
var sleepLoopTimeout;
function sleepLoop() {
gameActions();
sleepLoopTimeout = setTimeout(sleepLoop,5000);
}
function pause(){
clearTimeout(sleepLoopTimeout);
setTimeout(sleepLoop, 10000);
}
function gameActions() {
// Actions
}

var gameTimeout, sleepTimeout;
function game() {
gameTimeout = setTimeout(sleepLoop, 10000); //start in 10 seconds
}
function sleepLoop() {
sleepTimeout = setTimeout(gameActions, 5000); //start in 5 secs
}
function gameActions() {
sleepLoop();
}
//start it off:
game();
Other than the above, I am not sure what you are asking.
To kill (clear) the timeouts:
clearTimeout(gameTimeout);
clearTimeout(sleepTimeout);

var blocked = false;
function loopToBePaused()
{
if (blocked !== false)
{
// will check for blocker every 0.1s
setTimeout(loopToBePaused, 100);
return;
}
// payload
// normal loop now, e.g. every 1s:
setTimeout(loopToBePaused, 1000);
}
// somewhere in code run:
blocked = setTimeout(function() {
// blocking our loop'ed function for 10s
blocked = false;
}, 10000);
// this will block our main loop for 10s

Related

Timer: setTimeout and function call

function tick() {
seconds_lapsed++; // Break point.
}
function countdown() {
while(!stopped || !is_paused()){
setTimeout(tick, 1000); // 1 second.
show_counter();
}
}
Could you tell me why the interpreter doesn't stop at the breakpoint? The while loop works, hava a look at the screenshot.
The while loop is a "busy" loop, i.e. it keeps the JavaScript engine busy, so it will not process anything that is waiting in one of its event/job queues. This means that the user interface does not get updated, no input can be processed, and events produced by setTimeout are not consumed. In this example, tick can only get executed if the currently running code finishes. So the while loop must end first.
You should let tick execute, and only then check the condition:
var stopped = true;
var seconds_lapsed = 0;
document.querySelector("button").addEventListener("click", function() {
stopped = !stopped;
seconds_lapsed = 0;
this.textContent = stopped ? "Start" : "Stop";
if (!stopped) countdown();
});
function show_counter() {
document.querySelector("span").textContent = seconds_lapsed;
}
function is_paused() {
return document.querySelector("input").checked;
}
function tick() {
seconds_lapsed++;
}
function countdown() {
show_counter();
setTimeout(function () {
if (stopped) return; // stop the loop
if (!is_paused()) tick();
countdown(); // <--- this is the "loop"
}, 1000);
}
Seconds elapsed: <span>0</span><br>
<input type="checkbox">Paused<br>
<button>Start</button>
the following example might help you accomplish what you are after. Distinguish between setInterval() and setTimeout()
Basically the docs say:
setTimeout executes a function or specified piece of code once the timer expires.
setInterval repeatedly calls a function or executes a code snippet, with a fixed time delay between each call.
So if you use setInterval you don't need a while loop inside because it is already called "repeatedly"
var counter = $('#counter');
var stopped = false;
var seconds_lapsed=0;
var myInterval;
function tick() {
if(stopped) {
clearInterval(myInterval);
show_counter('FINISHED');
return;
}
show_counter(seconds_lapsed++);
}
function show_counter(message){
counter.html(message);
}
function countdown() {
myInterval = setInterval(tick, 1000);
}
function endCountdown(timeout) {
let timeoutId = setTimeout(function(){
stopped = true;
clearTimeout(timeoutId)
}, timeout);
}
countdown(); // start the countdown
endCountdown(5000); // ends the countdown after 5000 ms => 5sec
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="counter">counter</div>

Call on an interval after stopping it

In javascript, if you set a variable to the interval, and clear it, is there a way to turn it back on? Thanks. If you need code, please ask. I have tried just putting the interval name, but that returns a number. I have also tried putting it as a function, which returns an error.
var on = false;
var time = 0
function toggle() {
if (on === false) {
start()
on = true
} else {
stop()
on = false
}
}
function start() {
var interval = window.setInterval(function() {
add()
}, 1000)
console.log('1')
}
function stop() {
clearInterval(interval);
console.log('2')
}
function add() {
time = time + 1;
document.getElementById('time').innerHTML = time;
}
<div id='time'></div>
<button onClick="toggle()">Toggle</button>
Move your code that starts the setInterval into a function.
Clear the interval and then call the function again.
Once you clear an interval you cannoy restart it.
I don't think you need to clear and set again interval.
How about this approach:
var start = document.getElementById('start')
var stop = document.getElementById('stop')
var time = document.getElementById('time')
var isRunning = false
start.onclick = function() {
isRunning = true
}
stop.onclick = function() {
isRunning = false
}
function func() {
if (isRunning) {
time.innerHTML = +time.innerHTML + 1
}
}
setInterval(func, 1000)
<button id="start">start</button>
<button id="stop">stop</button>
<div id="time">0</div>
your code already supports the functionality you are asking for. you are just not stopping the interval as sabithpocker mentioned because of the interval variable scope. just use start() whenever you want to continue. since the add() function is using a global variable time then it won't matter if you stopped it and wanted it to recreate the interval later. also I enhanced the toggle flag assignment a bit.
I also recommend reducing the number of defined functions. you can put all this logic into one function or inject it from the caller for more dynamicity.
var on = false,interval;
var time = 0
function toggle() {
on=!on;
if (on == true) {
start();
} else {
stop();
}
}
function start() {
interval = window.setInterval(function() {
add()
}, 1000)
console.log('1')
}
function stop() {
clearInterval(interval);
console.log('2')
}
function add() {
time = time + 1;
document.getElementById('time').innerHTML = time;
}
<div id='time'></div>
<button onClick="toggle()">Toggle</button>

How to autorefresh my Ajax inside of a condition [duplicate]

Using setTimeout() it is possible to launch a function at a specified time:
setTimeout(function, 60000);
But what if I would like to launch the function multiple times? Every time a time interval passes, I would like to execute the function (every 60 seconds, let's say).
If you don't care if the code within the timer may take longer than your interval, use setInterval():
setInterval(function, delay)
That fires the function passed in as first parameter over and over.
A better approach is, to use setTimeout along with a self-executing anonymous function:
(function(){
// do some stuff
setTimeout(arguments.callee, 60000);
})();
that guarantees, that the next call is not made before your code was executed. I used arguments.callee in this example as function reference. It's a better way to give the function a name and call that within setTimeout because arguments.callee is deprecated in ecmascript 5.
use the
setInterval(function, 60000);
EDIT : (In case if you want to stop the clock after it is started)
Script section
<script>
var int=self.setInterval(function, 60000);
</script>
and HTML Code
<!-- Stop Button -->
Stop
A better use of jAndy's answer to implement a polling function that polls every interval seconds, and ends after timeout seconds.
function pollFunc(fn, timeout, interval) {
var startTime = (new Date()).getTime();
interval = interval || 1000;
(function p() {
fn();
if (((new Date).getTime() - startTime ) <= timeout) {
setTimeout(p, interval);
}
})();
}
pollFunc(sendHeartBeat, 60000, 1000);
UPDATE
As per the comment, updating it for the ability of the passed function to stop the polling:
function pollFunc(fn, timeout, interval) {
var startTime = (new Date()).getTime();
interval = interval || 1000,
canPoll = true;
(function p() {
canPoll = ((new Date).getTime() - startTime ) <= timeout;
if (!fn() && canPoll) { // ensures the function exucutes
setTimeout(p, interval);
}
})();
}
pollFunc(sendHeartBeat, 60000, 1000);
function sendHeartBeat(params) {
...
...
if (receivedData) {
// no need to execute further
return true; // or false, change the IIFE inside condition accordingly.
}
}
In jQuery you can do like this.
function random_no(){
var ran=Math.random();
jQuery('#random_no_container').html(ran);
}
window.setInterval(function(){
/// call your function here
random_no();
}, 6000); // Change Interval here to test. For eg: 5000 for 5 sec
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="random_no_container">
Hello. Here you can see random numbers after every 6 sec
</div>
setInterval(fn,time)
is the method you're after.
You can simply call setTimeout at the end of the function. This will add it again to the event queue. You can use any kind of logic to vary the delay values. For example,
function multiStep() {
// do some work here
blah_blah_whatever();
var newtime = 60000;
if (!requestStop) {
setTimeout(multiStep, newtime);
}
}
Use window.setInterval(func, time).
A good example where to subscribe a setInterval(), and use a clearInterval() to stop the forever loop:
function myTimer() {
}
var timer = setInterval(myTimer, 5000);
call this line to stop the loop:
clearInterval(timer);
Call a Javascript function every 2 second continuously for 10 second.
var intervalPromise;
$scope.startTimer = function(fn, delay, timeoutTime) {
intervalPromise = $interval(function() {
fn();
var currentTime = new Date().getTime() - $scope.startTime;
if (currentTime > timeoutTime){
$interval.cancel(intervalPromise);
}
}, delay);
};
$scope.startTimer(hello, 2000, 10000);
hello(){
console.log("hello");
}
function random(number) {
return Math.floor(Math.random() * (number+1));
}
setInterval(() => {
const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';//rgb value (0-255,0-255,0-255)
document.body.style.backgroundColor = rndCol;
}, 1000);
<script src="test.js"></script>
it changes background color in every 1 second (written as 1000 in JS)
// example:
// checkEach(1000, () => {
// if(!canIDoWorkNow()) {
// return true // try again after 1 second
// }
//
// doWork()
// })
export function checkEach(milliseconds, fn) {
const timer = setInterval(
() => {
try {
const retry = fn()
if (retry !== true) {
clearInterval(timer)
}
} catch (e) {
clearInterval(timer)
throw e
}
},
milliseconds
)
}
here we console natural number 0 to ......n (next number print in console every 60 sec.) , using setInterval()
var count = 0;
function abc(){
count ++;
console.log(count);
}
setInterval(abc,60*1000);
I see that it wasn't mentioned here if you need to pass a parameter to your function on repeat setTimeout(myFunc(myVal), 60000); will cause an error of calling function before the previous call is completed.
Therefore, you can pass the parameter like
setTimeout(function () {
myFunc(myVal);
}, 60000)
For more detailed information you can see the JavaScript garden.
Hope it helps somebody.
I favour calling a function that contains a loop function that calls a setTimeout on itself at regular intervals.
function timer(interval = 1000) {
function loop(count = 1) {
console.log(count);
setTimeout(loop, interval, ++count);
}
loop();
}
timer();
There are 2 ways to call-
setInterval(function (){ functionName();}, 60000);
setInterval(functionName, 60000);
above function will call on every 60 seconds.

SetTiemout in SetInterval?

I have a strange problem, well I'm trying to make a loop using setInterval but i want to have a SetTimeout inside as well.
Seems, from the comments, what you need is just
var init = function() {
setTimeout(function(){
console.log("Hi");
init(); // only call init here to start again if need be
}, 8000);
}
init();
based on the comment below, I'm assuming the interval needs to be "paused" sometimes because in your comment you say at some point, I have to delay one action - which implies that this delay isn't always necessary. Given that, you could write it as follows
var test = function() {
var interval = setInterval(function() {
if (someCondition) {
clearInterval(interval); // stop the interval
setTimeout(function(){
console.log("Hi");
test(); // restart the interval
}, 8000);
} else {
// this is done every second, except when "someCondition" is true
}
}, 1000);
}
or even
var running = true;
var test = function() {
var interval = setInterval(function() {
if (someCondition) {
running = false; // stop the interval
setTimeout(function(){
console.log("Hi");
running = true; // restart the interval
}, 8000);
} else if (running) {
// this is done every second, only when "running" is true
}
}, 1000);
}

How to get rid of javascript maximum stack size

I need this code to iterate for about 10 seconds (or better indefinitely) without causing javascript maximum stack size. I have comented setInterval because it's causing the problem!
var myToggle = false;
function myFunc () {
setTimeout(function () {
if (myToggle) {
console.log("red");
}
else {
console.log("yellow");
}
myToggle = !myToggle;
}, 500);
// setInterval(myFunc, 10000);
}
myFunc();
Call setInterval instead. setTimeout will call the inner function once. setInterval will continue calling until you cancel.
This usually a sign of bad design but the solution may be the following:
var myToggle = false;
function myFunc () {
var startTime = new Date()/1;
function wait () {
if (myToggle) {
console.log("red");
} else {
console.log("yellow");
}
myToggle = !myToggle;
if (new Date() < startTime + (10*1000)) { // exit condition
setTimeout(wait, 500);
}
}
wait();
}
myFunc();
FYI: Infinite callbacks, among the other things, slowdown the browser and consume battery on mobile devices.

Categories