The setTimeout method works strangely - javascript

I have created a method to let the user wait for certain period of time. (waiting window)
function hideMe()
{
document.getElementById('rotate').style.visibility= "hidden";
}
function showMe()
{
document.getElementById('rotate').style.visibility= "visible";
}
function wait()
{
showMe();
setTimeout(hideMe, 2000); // To show certain window for 2 seconds
}
But the window just flashes even I increase the time longer. It doesn't improve a lot.
Why is that?
What is the alternative method?
Well, I can't use jQuery in this project, sorry.
UPDATE
Sorry... I use visibility instead of display but it still can't work.
I found out that I will send some requests to server after the command wait() and it influences setTimeout().
like:
wait();
httpReq();
If I add alert("after wait()")
like:
wait();
alert("after");
The alert won't be executed after the wait();

in your code you are using
document.getElementById('rotate').style.display= "visible";
where display does not have "visible" property.
You either have to use "block","inline".
or you can also set display property to blank.
document.getElementById('rotate').style.display= "";
Check if this helps.
As per OP's comment
setTimeout is not synchronous command. if you want something to be execute out after the setTimeout is executed. You have to add it to setTimeout function. For Eg
setTimeout(function(){hideMe();alert("test");}, 2000);

Related

Calling JavaScript Function that has SetTimeout Assigned to It

I'm not 100% sure how setTimeout works in JavaScript. Say I have something like this:
$(document).ready(function() {
testTimeout();
});
function testTimeout() {
alert("testing timeout");
setTimeout(testTimeout, 5000);
}
This would display a popup window every 5 after the page is ready. What would happen if then I called testTimeout from a button click?
$("#button").click(function() {
testTimeout();
});
Would the button click call testTimeout and add another timeout every 5 seconds? Or, would the button click reset the timeout from when the button was pressed? The reason I am asking is because I would like to design something like this where I can pass a parameter to my timeout function. When the web page starts up, I have a default parameter. However, if I press a button, I would like my timeout function to be called right away and every 5 seconds after with my new parameter. But, I don't want the timeout function with the old parameter to continue repeating. How can I achieve this? Any help and understanding would be greatly appreciated.
This would display a popup window every 5 after the page is ready.
No it wouldn't, it would show an alert repeatedly with no delay and/or cause a "too much recursion" error, because setTimeout(testTimeout(), 5000) calls testTimeout and passes its return value into setTimeout, just like foo(bar()) calls bar and passes its return value into foo.
If you remove the ():
function testTimeout() {
alert("testing timeout");
setTimeout(testTimeout, 5000);
// here --------------^
}
Then it would do that.
What would happen if then I called testTimeout from a button click?
You'd end up with the function being called twice as often (more than once every 5 seconds), because every time you call it, it reschedules itself. A third time would make it more frequently still (three times/second), and so on.
If you want to avoid that, one option is to remember the timer handle and cancel any outstanding timed callback if you call the function before then:
var handle = 0;
function testTimeout() {
clearTimeout(handle); // Clears the timed call if we're being called beforehand
alert("testing timeout");
handle = setTimeout(testTimeout, 5000);
}
(I initialized handle with 0 because calling clearTimeout with a 0 is a no-op.)
Have you tried to asign variable to your setinterval;
var foo = setTimeout(testTimeout(), 5000);
and then when right event comes just destroy that variable.
clearInterval(foo);
And now you can asign it again...
In your case it would simply repeat endlessly, because you're executing the function instead of passing the reference. You should do it like this:
function testTimeout() {
alert("testing timeout)";
setTimeout(testTimeout, 5000);
}
Note the missing braces after testTimeout. This tells setTimeout to execute that function, instead of the result of that function, which is how your original code behaved.
" I would like my timeout function to be called right away and every 5 seconds after with my new parameter. But, I don't want the timeout function with the old parameter to continue repeating "
In order to achieve what you're trying to do you should remove the timeout:
var timeoutId;
function testTimeout() {
alert("testing timeout)";
clearTimeout(timeoutId );
timeoutId = setTimeout(testTimeout, 5000);
}
Notes:
You can stop the previous timeoutI from firing by catching the id returned from the setTimeout method and passing that to the clearTimeout method

What will be the sequence of execution of this javascript/Jquery code?

Ok, I am pretty new to jquery and Javascript.
I was reading about callback on w3school and it gives two examples.
Example1:
$("button").click(function(){
$("p").hide("slow",function(){
alert("The paragraph is now hidden");
});
});
Example2:
$("button").click(function(){
$("p").hide(1000);
alert("The paragraph is now hidden");
});
I understand that in first case alert will ONLY be executed after hide() function has finished.
However in second example it is possible that alert might execute before hide finishes.
This has caused some confusion in my understanding. Like for example is it possible that alert('hey') might get executed before alert which comes before it (one with mathmatical calculation) in following case..
$("button").click(function(){
alert(1+2+(3*4)..blah..blah);
alert('hey');
});
OR
in this case..
$("button").click(function(){
fn1();
fn2();
});
function fn1(){
for(var i=0;i<100;i++){
$('table').append(blah);
}
}
function fn2(){
alert('hey');
}
Is it possible that 'hey' might appear before fn1 has finished appending?
If so do I need to write every thing as callback??
To answer your question: No.
The key is that certain javascript functions are asynchronous. These really only come in two common categories:
XmlHttpRequest (i.e. AJAX) calls, where the browser goes out to the network to get something, and it lets the script continue running while it gathers the response.
timeouts and intervals, where you tell the browser to call some code after a delay. The script will continue unimpeded and then, when the time arises, the timeout code will run.
In your examples:
$("p").hide("slow",function(){
alert("The paragraph is now hidden");
});
The hide function in jQuery is timeout based. So your script does not have to wait for the animation to complete before it gets on with its business. jQuery provides a callback parameter so you can choose to have something happen after the animation completes if you want.
So in this example:
$("button").click(function(){
$("p").hide(1000);
alert("The paragraph is now hidden");
});
It is wrong to say the alert "might" execute before the hide finishes. Unless your code is executing so slowly that it takes more than 1 full second for an alert to show, it will execute before the hide completes. 1000ms is an eternity to a line of javascript.
$("button").click(function(){
alert(1+2+(3*4)..blah..blah);
alert('hey');
});
In this example, there is nothing asynchronous about the code. alert is a so called blocking call, meaning nothing happens in the script until you dismiss the alert. So you are guaranteed that the alerts will appear in order no mater how complex you make the parameter.
In fact, the complexity of the parameter has no bearing because it will evaluate in full before the resulting string is passed to the alert function.
So long story short, unless you're doing Ajax, setTimeout and setInterval, or using a third party library (which should document its behavior) your code will execute in order.
No. The reason the alert() occurs first in example 2 is because the hide() call is asynchronous. The hide() function is fired, but this has a 1000 millisecond delay. The alert() is fired instantly afterwards, not 1000 milliseconds afterwards, therefore it appears that the alert() was fired first.
In example 1 the alert() fires only when the hide() has completed, as this uses a callback function.
When using alert or confirm in Javascript, the browser is forced into a synchronous (existing or occurring at the same time) process where everything (even the loading of another page) halts until the user dismisses the dialog.
So when you alert something, browser will halt execution of other functions.
But jQuery hide and other animation functions are asynchronous (not existing at the same time) so that browser will go to next line without waiting for them.
For ex.
$(document).ready(function(){
fn1();
fn2();
});
function fn1(){
for(var i=0;i<100;i++){
$('body').append("<div>blah</div>");
console.log("blah!");
}
}
function fn2(){
console.log("Hey!");
}
Here hey will be logged after blah (100 times) as the browser waits for f1() to complete.
DEMO
But if you try something like:
$(document).ready(function(){
fn1();
fn2();
});
function fn1(){
for(var i=0;i<100;i++){
if(i%10==0)
{
fn2();
alert(true);
}
console.log("blah!");
}
}
function fn2(){
console.log("Hey!");
}
Then alert will show its way of working.
Also in jQuery:
$("p").hide("slow",function(){
// This is the call back function and not others.
});
The callback will be executed when any async or sync function first of all executes its tasks.
no it is not possible, for functions the JavaScript does them line by line but all in once, BUT it returns the result of the first one after giving the result of the second one! but as for the other example, it is obvious that hide() is going to take much longer to give the requested respond comparing to alert which is a browser built in function and that's why the alert appears to be working before hide(), I don't know the exact time that it takes to do these things but if you google it, you can learn them too if you need to!
BTW when an alert() pops up, it shuts down the whole javascript codes while it's on, just for you to know. ;)

JavaScript: setInterval and clearInterval, which way is correct?

Which way is correct and more efficient in using setInterval() and clearInterval()?
1.
something = setInterval(function() {
try {
...load something
clearInterval(something);
} catch (e) {
// error
}
}, 5000);
2.
something = setInterval(function() {
try {
...load something
} catch (e) {
// error
}
}, 5000);
setTimeout(something, 7000);
EDIT:
For #2, I meant setTimeout() instead of clearInterval().Has been changed.
I assume the interval you're passing into clearInterval is meant to be something.
Your second example will never fire your timer, because you clear the timer immediately after setting it. You're also passing an argument (7000) into clearInterval that won't get used (clearInterval only accepts one argument).
Your first example is right provided that you want to clear the repeated timer at the point where you're calling clearInterval from within the handler. Presumably that's in an if or similar, because if you want a one-off timed callback you'd use setTimeout, not setInterval.
EDIT:
For #2, I meant setTimeout() instead of clearInterval().Has been changed.
That completely changes the question. No, that's not correct. setInterval schedules the function to be called repeatedly on the interval you give it, you don't pass its return value into setTimeout.
If you need something to happen over and over again you use setInterval if you only need it to happen once use setTimeout (you can simulate setInterval by chaining multiple timeouts one after the other). Timeouts only happen once therefore you do no need to clear them. Also clearInterval does not take a time argument so the interval you set will be cleared before it ever executes since classic javascript is synchronous.
just to complete the answer, take many care with setInterval(). if your "...load something" take sometime more time to load than the time according (for a reason or another). it will just don't do it for this time and will wait the next call of setinterval.
I encourage to use setTimeout() as much as possible instead.
You can find find below the use cases that are, according to me, aswering to your questions:
For your case 1:
var something = setInterval(function() {
// Do stuff, and determine whether to stop or not
if (stopCondition) {
clearInterval(something);
}
}, 5000);
For your case 2:
var something = setInterval(function() {
// Do stuff
}, 5000);
// Pass a function to setTimeout
setTimeout(function() {
clearInterval(something);
}, 17000);

Switching between setTimeout function in javascript

I have setTimout function like this
setTimeout(function(){
//doing something here
},1000);
another setTimeout func like this right after the above func
window.setTimeout(function(){
//code here
},10000);
What I need to achieve is I need to read some files in first setTimeout function and do some processing,once the timeout over control should go to second timeout function,do some stuff there.Then get back to the first timeout function,do some processing there,when timeout over callback the second fun and so on..Like that I need to do for n number of files.
But whats happening is if I give for loop inside the first setTimeout fun,it process all the files and control is passed to second timeout fun with the last processed file.But what i want is to do that for each file??
How can i achieve this?Am newbie in Javascript. Any help?
function timeout1() {
console.log("This is timeout 1");
window.setTimeout(timeout2, 500);
}
function timeout2() {
console.log("This is timeout 2");
window.setTimeout(timeout1, 500);
}
// Kick it off.
timeout1();
Instead of using two Time outs why didn't you use wait like below?
setInterval(function(){alert("Hello")},3000);
Check this for a detailed explanation.
Hope this helps.
Please leave a feed back.

Javascript: Non-blocking way to wait until a condition is true

I have several ASP.NET UpdatePanels, each with an AsyncPostBackTrigger tied to the same button's serverside click event. Since only one UpdatePanel can be doing its thing at a time, I use .get_isInAsyncPostBack() of the PageRequestManager to prevent a user from being able to access another part of the page until the async postback is complete.
Another part of this page needs to dynamically update multiple update panels consecutively. Since the update panels use async triggers, calling __doPostBack("<%=ButtonName.ClientID %>", 'PanelId'); fires asynchonously. Because of this, it will quickly move along to the next iteration of the loop and try to update the next panel. However, the second iteration fails because there is already another update panel doing an async postback.
Ideally, there would be a way to wait until .get_isInAsyncPostBack() returns false without blocking other client activity.
Research has lead me to a lot people with my problem, almost all of whom are advised to use setTimeOut(). I do not thing this will work for me. I don't want to wait for a specified amount of time before executing a function. I simply want my Javascript to wait while another script is running, preferably wait until a specific condition is true.
I understand that many will probably want to suggest that I rethink my model. It's actually not my model, but one that was handed to our development team that is currently a total mess under the hood. Due to time contraints, rewriting the model is not an option. The only option is to make this work. I think that if I had a way to make the client code wait without blocking, my problem would be solved.
There is no such functionality such as wait or sleep in javascript, since it would stop browser from responding.
In your case I would go with something similar to following:
function wait(){
if (!condition){
setTimeout(wait,100);
} else {
// CODE GOES IN HERE
}
}
It's easy to make a mistake when calling setTimeout that will cause the JavaScript call stack to fill up. If your function has parameters, you need to pass those in at the end of the setTimeout parameter list like this:
function wait(param1, param2){
if (!condition){
setTimeout(wait, 100, param1, param2);
} else {
// CODE GOES IN HERE
}
}
If you pass parameters or even include empty () after the name of the function, it will be executed immediately and fill up the stack.
// This is the wrong way to do it!
function wait(param1, param2){
if (!condition){
setTimeout(wait(param1, param2), 100); // you'll get max call stack error if you do this!
} else {
// CODE GOES IN HERE
}
}
I needed to slow down a process and came up with a helpful little method.
const wait = (seconds) =>
new Promise(resolve =>
setTimeout(() => resolve(true), seconds * 1000)
);
And you can use it like this.
const doWork = async() => {
// After 3 seconds do something...
await wait(3);
console.log('work done');
}
This function calls condFunc which should return true when condition is met. When that happens readyFunc is called. checkInterval sets checking rate in milliseconds
var wait = function(condFunc, readyFunc, checkInterval) {
var checkFunc = function() {
if(condFunc()) {
readyFunc();
}
else
{
setTimeout(checkFunc, checkInterval);
}
};
checkFunc();
};
Usage:
wait(
function() { return new Date().getSeconds() == 10; },
function() { console.log("Done"); },
100
);
prints "Done" when current time is 10 seconds after minute

Categories

Resources