Prevent JS code to run, before function has ended - javascript

I can't wrap my head around this one?
WHY IS IT THAT MY:
.each loop runs right through even though I'm stalling things inside by 1000ms per loop?
The problem is that the window.location.href command runs TO EARLY before the setTimeout has finished? Same for the stopload() function which is also ended to early? I have seen something about recursive setTimeout functions is that what is needed here and how do I implement that?
function shop(clickedButton)
{
var buttonvalue = $(clickedButton).val();
startLoad();
pdel = 1000;
$("input:submit[value='buy']").each(function(index)
{
if(index != 1)
{
$("#backgroundPopup").text(index);
var submithing = this;
setTimeout(function(){ clicksubmitbutton(submithing); },pdel);
pdel += 1000;
}
});
stopLoad();
if(buttonvalue == "1")
{
window.scrollTo(0,0);
}
else
{
window.location.href = 'http://my.url';
}
}

Javascript has no notion of a sleep, or stall. Execution continues right past a setTimeout call. This function simply schedules a function to be run after the given number of milliseconds.
In order to get your desired behavior, you need to call the next iteration in the setTimeout callback function.
Something like:
function submitTheThing(index) {
if (done) { //some logic
return;
}
// do something
setTimeout(function() { submitTheThing(index+1); }, 1000);
}

Related

javascript while loop which can be executed once in 10 ms

My javacript code uses asynchronous functions.
now the main loop waits for 2 counters to be same .. which are being manipulated by those async functions.
code in main ..
while (counter1 != counter2) {
}
But i think this is taking all CPU and other async jobs are not able to proceed .
Is there any way so that the above while loop executes once in 10ms so that for the rest of the time
other async functions can run.
You could use setInterval (https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval).
var intervalId = setInterval(function() {
if (counter1 === counter2) {
clearInterval(intervalId);
} else {
// do stuff
}
}, 10);

Can I stop the execution of a function from outside that function?

I have this code:
function toStop(){
while(true){}
}
toStop();
Now, how can I stop this? Or how can I kill the current thread if this function call is somewhere in the setInterval running thread? Example:
var id = setInterval(function(){
toStop();
}, 1000);
//stop thread/timer with id here.
clearInterval doesn't work because it waits until the function call ends.
Thanks!
"Can I stop the execution of a function from outside that function?"
No, you can't programmatically.
JavaScript is single-threaded and if you run a piece of code that makes it infinitely busy, such as while(true);, then nothing else will ever be able to execute.
Calling such a piece of code within setTimeout or setInterval will have the same result, since the callback of these gets executed in the only thread we have as well.
However, you can create a timed recurring execution using setInterval or setTimeout, which can be stopped.
var timerId = setInterval(function () {
//Process an iteration of the loop in here
//If you cause an infinite loop in here, you will have the same issue
}, 50);
//stop the timer after ~3 seconds
setTimeout(clearInterval.bind(null, timerId), 3000);
Notes:
4 is the lowest interval that could be honored as specified in the SPEC.
setInterval will stack if the callback takes more time to execute than the specified interval. For that reason I never use setInterval and always use setTimeout.
Timer intervals are not guaranteed to be accurate
e.g. with setTimeout
var stopProcessing = startProcessing();
//Stop processing after ~3 seconds
setTimeout(stopProcessing, 3000);
function startProcessing() {
var timerId;
!function process() {
//Do some processing
//Continue processing in ~50 ms
timerId = setTimeout(process, 50);
}();
return function () { clearTimeout(timerId); }
}
Instead of an infinite loop, just use an if statement and wrap it in an interval:
var shouldContinue = true;
var interval = 0;
function toStop() {
if (interval == 0) {
interval = setInterval(function() {
if(shouldContinue) {
...
}
else {
clearInterval(interval);
interval = 0;
}
}, 200); // Or whatever interval makes sense
}
}
toStop();
// ...
shouldContinue = false;
See this principle in action here.
No, you can't programmatically, as #plalx said but you could try this: declaring a binding outside and check on that to continue or stop the loop:
let letMeGoOut;
function toStop(){
while(letMeGoOut != false)
}
toStop();
Here, I've created a function on mouseover that triggers a loop changing the opacity of the h1. It goes on till the mouse cursor moves out and is over something else in the page.
Here is the example: https://codepen.io/Mau-Di-Bert/pen/VqrRxE

Confused with set timeout

I'm really confused how these work...the timeout does not seem to keep running it calls begin_anim once and then thats it....
So am hoping someone can see where i went wrong and explain how I implement this?
This is my code:
//test data:
//type = 'up';
//div = document.getElementById('theid');
//marginL = -400;
function timeout_begin(type,div,marginL){
setTimeout(begin_anim(type,div,marginL),1000);
}
function begin_anim(type,div,marginL){
if(type == 'up'){
if(marginL >= '-200'){
if(marginL > '-200'){
div.style.marginLeft = '-200px';
}
return false;
}
marginL += 2;
div.style.marginLeft = marginL+'px';
}
return false;
}
Hope you can help!
You're looking for setInterval!
Also, it's probably better to pass an actual function in, and you can hold a reference to the loop so you can stop it running later if you want to:
var animationLoop = setInterval(function () {
begin_anim(type, div, marginL);
}, 1000);
clearInterval(animationLoop); // This would then stop the loop.
First, you want setInterval, not setTimeout
Second, you'll pass a reference to a function, not a call to a function. Something like:
function timeout_begin(type,div,marginL)
{
setTimeout(
function() {
begin_anim(type,div,marginL);
},
1000
);
}
setTimeout is supposed to call the function only once.
if you want to call the method repeatedly use setInterval(function(){}, 1000/*duration*/)
setTimeout is only expected to execute the function once after the given timeout. See the documentation here: http://www.w3schools.com/jsref/met_win_settimeout.asp
You're probably looking for setInterval (http://www.w3schools.com/jsref/met_win_setinterval.asp) which executes the code at the interval you set until clearInterval is called.

Javascript setTimeout function starts executing too many times

I created a loop with setTimeout function and it comes to a problem after 2nd or 3rd step it call's itself because it starts excecuting twice at the time. This is what my function looks like:
var value = 70,
intervalID = null;
function interval() {
intervalID = setTimeout(countDown, 1000);
}
function countDown() {
value--;
if(value > 0) {
clearTimeout(intervalID);
interval();
} else {
endInterval();
}
}
function endInterval() {
// do something
}
If I console the variable value its 69, 68 and after that it starts decreasing variable value twice in one function call. I'm not calling function countDown() anywhere but from one place.
What could be the problem?
Edit: this code works now.
I'd recommend you to "sanitize" the timeouts by stopping previous one.
function interval() {
clearTimeout(intervalID);
intervalID = setTimeout(countDown, 1000);
}
However it looks like control of symptoms instead of sickness' cause. So it would be better to detect the cause of the issue.

Executing code after clearInterval

I have a setInterval calling a loop which displays an animation.
When I clearInterval in response to a user input, there are possibly one or more loop callbacks in queue. If I put a function call directly after the clearInterval statement, the function call finishes first (printing something to screen), then a queued loop callback executes, erasing what I wanted to print.
See the code below.
function loop() {
// print something to screen
}
var timer = setInterval(loop(), 30);
canvas.onkeypress = function (event) {
clearInterval(timer);
// print something else to screen
}
What's the best way to handle this? Put a delay on the // print something else to screen? Doing the new printing within the loop?
Edit: Thanks for the answers. For future reference, my problem was that the event that triggered the extra printing was buried within the loop, so once this executed, control was handed back to the unfinished loop, which then overwrote it. Cheers.
You could also use a flag so as to ignore any queued functions:
var should;
function loop() {
if(!should) return; // ignore this loop iteration if said so
// print something to screen
}
should = true;
var timer = setInterval(loop, 30); // I guess you meant 'loop' without '()'
canvas.onkeypress = function (event) {
should = false; // announce that loop really should stop
clearInterval(timer);
// print something else to screen
}
First of all, you probably meant:
var timer = setInterval(loop, 30);
Secondly, are you sure calling clearInterval does not clean the queue of pending loop() calls? If this is the case, you can easily disable these calls by using some sort of guard:
var done = false;
function loop() {
if(!done) {
// print something to screen
}
}
var timer = setInterval(loop(), 30);
canvas.onkeypress = function (event) {
clearInterval(timer);
done = true;
// print something else to screen
}

Categories