Constructor function "creates" infinite loop in JS - javascript

I noticed some weird behavior in constructor functions. This code loops infinitely and I don't know why.
function thing(){
this.start=function (){console.log(this.msg)};
this.msg="Starting...";
setInterval(() => {this.start()},1000)
}
<button onclick="new thing()">Create a new thing!</button>
I've searched about this but I found nothing that explains this. Please someone help me and answer why this happens.
Thanks.

Are you sure you wanted to use setInterval not setTimeout? The former will callthis.start every 1 second, while the latter will be called once after 1 second,
Please take a look at the below links explaining both functions:
setInterval
https://developer.mozilla.org/pl/docs/Web/API/Window/setInterval
setTimeout
https://developer.mozilla.org/pl/docs/Web/API/Window/setTimeout
Correct snippet should be:
function thing(){
this.start=function (){console.log(this.msg)};
this.msg="Starting...";
setTimeout(this.start(), 1000)
}
<button onclick="new thing()">Create a new thing!</button>

It does so because setInterval() sets up an... You've guessed it! Interval, which continues to execute it's contents at the interval you've set (1000ms in this example).
setTimeout() will delay execution once at the set delay.

Yes setInterval will call after 1 sec so if you want to stop that you need to use clearInterval.

From the W3School documentation:
Definition and Usage
The setInterval() method calls a function or evaluates an expression at specified intervals (in milliseconds).
The setInterval() method will continue calling the function until clearInterval() is called, or the window is closed.
The ID value returned by setInterval() is used as the parameter for the clearInterval() method.
Tip: 1000 ms = 1 second.
Tip: To execute a function only once, after a specified number of milliseconds, use the setTimeout() method.
So you may want to do:
function thing(){
this.start=function (){console.log(this.msg)};
this.msg="Starting...";
setTimeout(() => {this.start()}, 1000)
}
<button onclick="new thing()">Create a new thing!</button>

setInterval is actually supposed to start an interval (timed loop).
Also, you are executing the function rather than binding it :) Common mistake.
onclick="new thing()"
https://developer.mozilla.org/de/docs/Web/API/WindowTimers/setInterval
Your code can be done much simpler:
const start = () => setTimeout( () => console.log(200), 1000)
<button onclick="start">Start!</button>
In most cases, you will not need objects in JS. Functions as first-class objects are a very powerful feature of JS.

Related

Can't work setTimeout in componentDidMount

Try to build setTimeout() in React js. I setup this in componentnDidMount() but it works only once. Not working loop.
The code:
componentDidMount() {
setTimeout(console.log("hello"), 1000);
}
The warning show:
[Violation] 'setInterval' handler took 99ms
How can I repeat this function?
setTimeout(function, waitTime)
when you pass a function to the setTimeout method, the method waits for a specified amount of time waitTime, and it calls the function function.
But passing in console.log('hello') only simply logs out "hello", but does not return anything and thus does not actually pass a function or callable into the method.
Many ways to go around this:
setTimeout(function(){console.log("hello");},1000); //passes an actual function
setTimeout(()=>{console.log("hello");},1000); //lambda, passes an actual function
setTimeout(()=>console.log("hello"),1000); //same here
Also, if it was supposed to be repeated over intervals, then use setInterval (same arguments as setTimeout).
Use setInterval(). Here is a good explanation: setTimeout or setInterval?
setTimeout()
setTimeout() only execute one time when the time reached.
setInterval()
setInterval() is an interval based function and execute repeatedly when the interval is reached.
And examples for setTimeout() and setInterval(). Hope it helps.

a function that only calls input function f every 50 milliseconds

I am new to js.
I am trying to make a function that only calls input function f every 50 milliseconds.
wrote the code in the fiddle using setTimeout.
but isn't doing exactly what I wanted it to do
can you tell me how to fix it.
providing code below
https://jsfiddle.net/1pqznbgt/
function callSeconds(f){
setTimeout(function(){
alert("testing");
}, 500)
}
You are looking for setInterval instead of setTimeout (setTimeout will execute once, setInterval will execute at an interval)
The 500 in your sample means 500ms rather than 50ms
You will want to call f rather than your anonymous function, so:
What you are looking for is something like:
function callSeconds(f){
setInterval(f, 50);
}
The problem I see is that every time you call an alert() you are stopping execution of JavaScript and each browser can implement the alert differently . setTimeout() only executes once so if you call the function it will wait 500ms and issue an alert if you want a piece of code to operate continually you must use the setInterval() function but you still have the problem of how the browser chooses to handle the alert() function, normally an alert pauses execution of the current code, what effect that has on a timed execution function I do not know. I would try execution on something that does not pause or stop execution of the script. I also notice that in the code segment you have not invoked the parent function that would call the setTimeout function.
You can do one of 2 things here.
First, don't use setTimeout.
Instead use setInterval (f,50).
Or recursively call the function as so:
function foo (f){
f();
setTimeout (foo,50);
}

js fade in onLoad with for-loop, styles, and setInterval not working?

Why when calling fadeIn() onLoad does the browser run through the loop immediately. In other words there is an issue with either the setInterval or the Opacityto().
function Opacityto(elem,v){
elem.style.opacity = v/100;
elem.style.MozOpacity = v/100;
elem.style.KhtmlOpacity = v/100;
elem.style.filter=" alpha(opacity ="+v+")";}
function fadeIn(){
elem=document.getElementById('nav');
for (i=0;i==100;i++){
setInterval(Opacityto(elem,i),100);}
}
I think someone will tell me this can be done easiest with jQuery but I'm interested in doing it with javascript.
Thanks!HelP!
You've got several problems with your fadeIn() function:
A. Your for loop condition is i==100, which is not true on the first iteration and thus the body of the for loop will never be executed (the i++ won't ever happen). Perhaps you meant i<=100 or i<100 (depending on whether you want the loop to run 101 or 100 times)?
B. Your setInterval code has a syntax error EDIT: since you've updated your question to remove the quotes - setInterval expects either a string or a function reference/expression. So you need to either pass it the name of a function without parentheses and parameters, or a function expression like the anonymous function expression you can see in my code down below. in the way you try to build the string you are passing it. You've got this:
"Opacityto("+elem,i+")"
but you need this:
"Opacityto(elem," + i + ")"
The latter produces a string that, depending on i, looks like "Opacityto(elem,0)", i.e., it produces a valid piece of JavaScript that will call the Opacityto() function.
C. You probably want setTimeout() rather than setInterval(), because setInterval() will run your Opacityto() function every 100ms forever, while setTimeout() will run Opacityto() exactly once after the 100ms delay. Given that you are calling it in a loop I'm sure you don't really want to call setInterval() 100 times to cause your function Opacityto() to be run 100 times every 100ms forever.
D. Even fixing all of the above, your basic structure will not do what you want. When you call setInterval() or setTimeout() it does not pause execution of the current block of code. So the entire for loop will run and create all of your intervals/timeouts at once, and then when the 100ms is up they'll all be triggered more or less at once. If your intention is to gradually change the opacity with each change happening every 100ms then you need the following code (or some variation thereon):
function fadeIn(i){
// if called with no i parameter value initialise i
if (typeof i === "undefined") {
i = -1;
}
if (++i <= 100) {
Opacityto(document.getElementById('nav'), i);
setTimeout(function() { fadeIn(i); }, 100);
}
}
// kick it off:
fadeIn();
What the above does is defines fadeIn() and then calls it passing no parameter. The function checks if i is undefined and if so sets it to -1 (which is what happens if you call it without passing a parameter). Then it increments i and checks if the result is less than or equal to 100 and if so calls Opacityto() passing a reference to the element and i. Then it uses setTimeout() to call itself in 100ms time, passing the current i through. Because the setTimeout() is inside the if test, once i gets big enough the function stops setting timeouts and the whole process ends.
There are several other ways you could implement this, but that's just the first that happened as I started typing...
My guess is that there is a nasty comma inside the setInterval, messing the argument list:
"Opacityto("+elem,i+")"
^^^
here
You could try quoting the comma
+ "," +
but eval is evil so don't do that. The good way is to pass a real callback function:
function make_opacity_setter(elem, i){
return function(){
OpacityTo(elem, i);
};
}
...
setTimeout( make_opacity_setter(elem, i), 1000);
Do note that the intermediate function-making-function is needed to avoid the nasty interaction between closures and for-loops.
BTW, when you do
setInterval(func(), 1000)
you call func once yourself and then pass its return value to setInterval. since setInterval receives a junk value instead of a callback it won't work as you want to.

Javascript setTimeout ignoring time parameter

It's not the first time I've used setTimeout(), but I can't figure out what the problem is. The code part of the setTimeout() is executing correctly, but it is executing immediately without the delay. If anyone can see the problem, that would help. Here's the code:
if(token==1){
img1.src=ssImages[imgNum];
num1=0;
num2=10;
setTimeout('crossFade()',2500);
}
Are you sure this is the code? If it executes immediately there are usually two reasons:
The developer thought the time is specified in seconds - but 2500 is fine, that's 2.5 seconds.
He calls the function immediately (e.g. setTimeout(foo(), 1234));
But none of the reasons apply to your code so check the rest of the code if there are any other calls to that function.
Anyway, you should really pass a function instead of a string:
setTimeout(crossFade, 2500);
Or, if you need to specify any arguments:
setTimeout(function() {
crossFade(...);
}, 2500);
I agree with Theifmaster. The window. setTimeout method takes two arguments:
1) Function OR Expression
2) Time in ms
In your code you provide a string or an Expression :
setTimeout('crossFade()',....)
This is generally discouraged as with the use of eval. You should pass a function - either named:
setTimeout(crossFade,....)
OR as suggested anonymous:
setTimeout(function(){crossFade()},....
This is about all you can do to trouble shoot this code unless you provide an example ok jsfiddle for us to see the context this is called.

How does jQuery accomplish its asynchronous animations?

...or more specifically, how are they able to create animations via javascript, which is synchronous, without holding up the next javascript statement.
It's just a curiosity. Are they using a chain of setTimeout()? If so, are they set early, each one with a slightly longer duration than the previous, and running parallel? Or are they being created through a recursive function call, therefore running in series?
Or is it something completely different?
There is an alternative to setTimeout() called setInterval() which will call the function you pass as argument at regular intervals. Calling setInterval will return a value which can be passed to clearInterval to stop the function from being called.
With jQuery 1.4.2 on lines 5534 - 5536:
if ( t() && jQuery.timers.push(t) && !timerId ) {
timerId = setInterval(jQuery.fx.tick, 13);
}
Notice the setInterval for jQuery's tick method that triggers a step in an animation.
Chained calls to setTimeout aren't really "recursive". If one setTimeout function, when called, sets up another timeout with itself as the handler, the original invocation will be long gone by the time the new timeout occurs.
Using setTimeout instead of setInterval is (to me) often more flexible because it lets the timed code adapt (and possibly cancel) itself. The general pattern is to set up a closure around the setTimout call so that the data needed by the timed process (the animation, if that's what you're doing) is available and isolated from the rest of the app. Then the timeout is launched on its initial run.
Inside the timeout handler, "arguments.callee" can be used for it to refer to itself and reset the timeout for subsequent "frames."

Categories

Resources