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.
Related
I am trying to use nested timeOut with the same names which is actually works like a loop, not exactly like it.
I try to use this example:
let i = 1;
setTimeout(function run() {
func(i);
setTimeout(run, 100);
}, 100);
from this link.
As you see in this link, I cant use interval and loop.
Here is my actual code:
let i = 0;
let x = setTimeout(async function run() {
if(i == 2) {
// I want to stop my x here completly
console.log(i)
clearTimeout(x);
}
try {
//some code here e.g:
console.log(10)
} catch (err) {
//some other code here e.g:
console.log(err)
}
i++;
x = setTimeout(run, 800);
}, 800);
And my output:
10
10
2
10
10
... //never stops
I also saw this link, but it is not my case.
Could any body please do something so that I can stop x completely?
Thanks in advance.
You need not the timeout reference, because if inside of the function the reference is invalid, because the timeout is called. Then you need to stop just to return.
let i = 0;
setTimeout(async function run() {
if (i == 2) {
console.log(i)
return
}
try {
//some code here e.g:
console.log(10)
} catch (err) {
//some other code here e.g:
console.log(err)
}
i++;
setTimeout(run, 800);
}, 800);
Because when you clearTimeout you don't stop it by return. So your timeout will set another timeout with x = setTimeout(run, 800);. All you need to do is return your clearTimeout(x) to stop your timeout function.
return clearTimeout(x);
In your code, I don't see any reason you need to clear timeout. Timeout run only once time. So if you execute it. It is done.
I have a custom setInterval function that can modify the interval as it runs. I would like to be able to return a variable that the caller can modify later on. Similar to how clearInterval() works.
Custom Set Interval Function
customSetInterval(callback, interval) {
let stop = false;
this.startInterval(callback, interval, stop);
return stop;
}
startInterval(callback, interval, stop) {
if (stop) {
return;
}
setTimeout(() => {
callback();
interval += 100;
this.startInterval(callback, interval, stop);
}, interval);
}
My current implementation doesn't work because I'm simply returning the value. Not the variable itself. Is it possible to do something like this in JS?
Example Execution
let stop = this.devicewise.customSetInterval(() => {
console.log('HELLO!');
}, 1000);
setTimeout(() => {
console.log('stopping!');
stop = true;
}, 5000);
If this is not possible I plan on creating a boolean hashmap that I add to every time I start. Then create a customClearInterval function to modify that hashmap.
Seems like you wanted a one-time execution with the callback, maybe something like that:
class CustomInterval {
constructor() {
this.id = -1;
}
start(callback, interval) {
console.log(`executing callback in ${interval}ms`);
this.id = setTimeout(() => {
callback();
console.log('callback fired');
}, interval);
}
stop() {
clearTimeout(this.id);
console.log('stopped');
}
}
// ...
let j = new CustomInterval();
j.start(() => {
// do stuff here
}, 5000);
// after some other operations, you decided to cancel the above delayed execution
// no problem.
j.stop();
I have a function that is used to send messages and that is called multiple times in a sec.
But I want to call that function once a sec and delay other calls of that function with another 1-second of the previous call.
So that only that function run in the background and called once in a second, no matters how many times it is called it will delay each call to one second ahead.
For example:
function foo(a) {
console.log(a)
}
foo('one');
foo('two');
foo('three');
in the above example, foo is called three times within a sec but I want to have it called like after the 1 second it should return "one" after 2 seconds it should return 'second' and so on and it should be asynchronous.
How can I do this?
The technology I am using is Javascript.
Thanks
Well this is the first thing I came up with - perhaps it's crude.
var queuedUpCalls = [];
var currentlyProcessingCall = false;
function foo(a) {
if (currentlyProcessingCall) {
queuedUpCalls.push(a);
return;
}
currentlyProcessingCall = true;
setTimeout(function(){
console.log(a);
currentlyProcessingCall = false;
if (queuedUpCalls.length) {
var nextCallArg = queuedUpCalls.shift();
foo(nextCallArg);
}
},1000);
}
foo('one');
foo('two');
foo('three');
For each call, if you're not currently processing a call, just call setTimeout with a delay of 1000ms. If you are processing a call, save off the argument, and when the setTimeout that you kicked off finishes, process it.
Somewhat improved answer using setInterval:
var queuedUpCalls = [];
var timerId;
function foo(a) {
queuedUpCalls.push(a);
if (timerId) {
return;
}
timerId = setInterval(function(){
if (!queuedUpCalls.length) {
clearInterval(timerId);
timerId = null;
return;
}
var nextCallArg = queuedUpCalls.shift();
console.log(nextCallArg);
}, 1000);
}
foo('one');
foo('two');
foo('three');
Here is a simple queue system, it basically just pushes the functions onto an array, and then splice's them off every second.
const queue = [];
setInterval(function () {
if (!queue.length) return;
const f = queue[0];
queue.splice(0, 1);
f();
}, 1000);
function foo(a) {
queue.push(function () {
console.log(a)
});
}
foo('one');
foo('two');
foo('three');
you could use this to run the main code first and then run some more code a little later.
function firstfunction() {
alert('I am ran first');
setTimeout(function(){ alert('I am ran 3 seconds later') }, 3000);
}
<button onclick="firstfunction();">click me</button>
function foo(a)
{
if (typeof foo.last == 'undefined')
foo.last = Date.now();
var now = Date.now();
if (now - 1000 > foo.time)
foo.last = now;
setTimeout(function()
{
console.log(a);
}, (foo.last += 1000) - now);
}
This will queue each console.log call with intervals of 1 second, the first call will also be delayed by 1 second.
You could do this:
function foo() {
console.log(“ran”);
}
setInterval(foo, 1000);
In the last line, writing foo() without parenthesis is intentional. The line doesn’t work if you add parentheses.
var i = 3400;
function progress() {
i = 34000;
window.setInterval(function () {
i = i - 100;
document.getElementById("progress").firstChild.data = i;
}, 100);
}
This code is getting faster and faster. The function progress is called every 3 seconds, but I can't change the it's called because it's event based. After around 10 calls i is getting negative!
Umm....
Do not use setInterval
You probably want to use setTimeout
Since progress is called every 3 seconds, you need to avoid that it creates new intervals repeatedly. Using clearTimeout resets the timer anytime you call progress. However, without knowing what exactly you want to achive it's difficult to provide an accurate answer.
var timeout;
function counter(count) {
document.getElementById("progress").firstChild.data = count;
if (count >= 0) {
timeout = window.setTimeout(function() {
counter(count-100);
}, 100);
}
}
function progress() {
window.clearTimeout(timeout);
counter(3400);
}
Try this
var i = 3400;
function progress() {
i = i - 100;
document.getElementById("progress").firstChild.data = i;
window.setTimeout('progress();', 100);
}
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