How to halt Javascript code without alert - javascript

Is, is there any function which does the exact same thing as alert except doesn't bring up an alert box? (a function which halts ALL executing JS code for a given amount of time, but doesn't bring up an alert message).
setTimeout doesn't work since it only halts the cod which is inside the setTimeout function.

a javascript function that will stop your code for some time is setTimeout(),
for more information on how to use this function please reffer to the following link : http://www.w3schools.com/jsref/met_win_settimeout.asp

You could split it into two functions and have the first initiate a time-out.
function func1(){
//do stuff
setTimeout('func2',2000);
}
function func2(){
//do some more
}

The function setTimeout will execute for later whatever function you pass to it. So it will not really pause the execution of your code, unless the code is split into parts and placed within calls of setTimeout. Maybe that is an approach.
Another approach could be to use delay function (http://api.jquery.com/delay/) along your jquery calls.
But in all cases the best is to find out what is causing this behaviour and fix it in code.

Have you tried using the DOM elements rather than JQuery to create the new node.
http://www.w3schools.com/jsref/met_node_appendchild.asp

var startTime = new Date().getTime();
while(new Date().getTime() < startTime + 1000) {}
This waits for 1000ms / 1 sec.
During that time, your browser is completely unresponsive and possibly doesn't render any stuff you may be waiting for, but hey, ... there you go ;)

Related

Understanding JavaScript's single-threaded nature

I've been reading John Resig's "Secrets of a JavaScript Ninja" and it explains that JavaScript is single-threaded. However, I tried testing this and I'm not sure what to take away from here:
// executing this in browser
(function () {
// throw something into event queue
setTimeout(function () {
alert("This will be called back after 1 second.");
}, 1000);
// arbitrary loop to take up some time
for (var i = 0; i < 10000; i += 1) {
console.log(i);
}
})();
Maybe I'm not understanding exactly what being single-threaded means, but I thought that the setTimeout callback wouldn't execute until all of the outer anonymous function is complete. However, running this in the browser shows that the callback function gets called while i's are still being outputted onto the console. To me, this seems like there's 2 threads with anonymous function's invokation occupying 1 thread and then the callback using the 2nd thread.
Can someone help un-confuse me?
console.log() is a weird function in some browsers (like Chrome) and is not synchronous itself so you can't really use it to gauge the single threadedness. What you are probably seeing is that the JS engine executes all the console.log() statements and then the setTimeout() runs to show the alert and, in parallel (in some other process that isn't javascript) all the data is being shown in the console.
Javascript is indeed single threaded. In your example, the setTimeout() callback will not execute until your for loop is done.
You can illustrate it better like this:
(function () {
// throw something into event queue
setTimeout(function () {
alert("This will be called back after 1 second.");
}, 1000);
function now() {
return new Date().getTime();
}
var start = now();
// loop for 1.2 seconds
while (now() - start < 1200) {}
alert("Looping done");
})();
Working jsFiddle demo: http://jsfiddle.net/jfriend00/3sBTb/
This is a bit of a tricky concept to understand. Throwing in things like event listeners also further muddies up the picture.
A simple way to think of it is as if you have a conveyor belt. You have your normal function calls all evenly spaced out, with room in between.
Things that are asynchronous things (timeouts, triggered events, etc.) fill those spots. There isn't an infinite amount of room between each of those normal calls, so it fits what it can from this queue, does a little more of the normal synchronized functions, fills some more space with asynchronous, etc.
The affect appears to be somewhat multi-threaded (and indeed you can cause race conditions of a sort with asynchronous calls). In many cases, the distinction doesn't matter. However, it is important to remember this.
However, when you try to debug things, especially when using tools like Chrome's console.log, it can look like things are scrambled because console.log itself is asynchronous (if it were synchronous, it would freeze your script on a long function).
You can see this yourself if you output something like this:
var input = document.createElement('input');
input.setAttribute('value', 0);
function inc() {
input.setAttribute('value', parseInt(input.getAttribute('value'))+1);
console.log(input);
if (parseInt(input.getAttribute('value')) < 100) {
setTimeout(inc, 10);
}
}
inc();
JSFiddle: http://jsfiddle.net/c2PnP/
What this script does it creates an input element, then every 10 milliseconds, it increments the value of input, then outputs the input element. It repeats 100 times (until value = 100).
If you look at your console, you'll notice that some of the values will be duplicated, it won't be a smooth progression. For example, on a run I just did, I see 5 inputs with a value of "100" and gaps for the missing numbers. This is because console.log is running asynchronously and only outputting when it gets the gap to do so.
(Note: If you have a super fast computer, you may need to decrease the time to something smaller, like 1, and/or increase the number of iterations to a bigger number).
John Resig covered this well. Summarizing:
"JavaScript can only ever execute one piece of code at a time (due to
its single-threaded nature)... when an asynchronous event occurs (like
a mouse click, a timer firing, or an XMLHttpRequest completing) it
gets queued up to be executed later.... After the initial block of
JavaScript finishes executing the browser immediately asks the
question: What is waiting to be executed? The browser then picks one
and executes it immediately. The [rest] will wait until the next
possible time, in order to execute."

How can I write a function that takes X amount of seconds?

I want to write a javascript function that takes very close to 5 seconds to run. How can I make that guarantee?
I have tried
function wait(numSeconds) {
var end = new Date().getMilliseconds() + numSeconds * 1000;
while (new Date().getMilliseconds() <= end) {}
}
but this just crashes the page.
You cannot freeze the page without freezing the page.
You're trying to write a function that runs for 5 seconds straight.
Javascript runs on the UI thread, so the page will be frozen whenever any code runs.
In short, you can't do that.
You need to write asynchronous code, probably by using setTimeout().
you can use:
var t = setTimeout(function(){alert('done')},5000);
If you want to wait 5 seconds before doing something, use setTimeout or setInterval. Otherwise, just eating up user time is a bad idea. In fact, the browsers will interrupt your script if it takes too long to do something, which your function most certainly will do.
(Ignoring for the moment why you shouldn't really do this...)
The reason your code is freezing the browser is that your while condition will never become true (for numSeconds of 1 or more).
The .getMilliseconds() method returns just the milliseconds part of the date, i.e., a number between 0 and 999. For numSeconds of 1 of more your end will always be greater than 999.
Try using .getTime() instead of .getMilliseconds(). Or if you don't care about supporting old browsers uses Date.now().
You could just use javascripts setTimeout instead of your own wait function.
setTimeout excecutes a function after a certain amount of time.
For example:
setTimeout(function(){}, 5000);
Would just wait 5 seconds.
See more at w3schools.
Strictly speaking, what you ask cannot be done because, as you've seen, the page will freeze while you wait.
As a practical matter, though, I suspect that what you really want is the something like this:
function waitawhile() {
setTimeout( function() {
alert('5 seconds has passed');
}, 5000);
}

Sleep function in Javascript

I'm new to JavaScript from Java, and I'm trying to implement a sleep(millis) function. Basically I need to make a request to an endpoint, and if it returns an error, wait a while and make the request again...
I've found JavaScript's setTimeout() function, but it has a strange (for me) behaviour, because it seems that the code is still running, and I don't want to do anything but wait...
After a little research I've found this function here:
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
With this function I achieve exactly what I want, but I understand it may not be the proper way to do it and I didn't find any other solutions like this... So, I'd like to know, in your opinion, is this:
A perfectly valid solution?
A not too bad workaround?
Just painful to your eyes?
Well, opinions will vary. I can understand you though, JavaScript doesn't have a real sleep function like Java or any other language (like Perl, Bash, PHP, etc)
http://devcheater.com/ shows multiple variations, but also check out these Stackoverflow topics:
What is the JavaScript version of sleep()?
What's the best way to implement a sleep function JavaScript?
How to make a REAL sleep() in JavaScript?
You say you don't like setTimeout, but basically, that's what you need to do.
function myFunc() {
// Do the work
setTimeout(myFunc, sleepInterval);
}
(Assuming you're trying to create a repeating schedule, if not, call your other function rather than myFunc again).
You can (and probably should) of course add some termination logic as well.
Then start your work with myFunc(). You could also use setInterval, but it can cause some problems if your intervals start to overlap.
Regarding your solution, I select option 3...
There is no sleep function in Javascript, and you should consider using window.setTimeout to call the next operation. I certainly would not burn cycles in a for loop. But if you must wrap it in a function named sleep then here is an example to give you an idea.
function sleep(callBack, milliSecs) {
setTimeout(callBack, milliSecs);
}
function first() {
console.log("first");
}
function second() {
console.log("second");
}
first();
sleep(second, 5000);
On jsfiddle
The problem in this code is that is stays busy all the time until the code finishes. This may cause a warning dialog in many browsers, and it also slows the page down.
Here I would still prefer to use the setTimeout function. The syntax is quite simple:
setTimeout("codeToBeExecuted()", milliseconds);
You can simplify it by saving the code after sleeping in a function, and passing the needed data in global variables or like this:
setTimeout('whenDone(' + numericData + ', "' + stringData + '")', milliseconds);
JSFiddle

Javascript setTimer

I'm having a hard time understanding the logic behind the setTimer method in javascript.
<html><head>
<script>
function Timer () {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
document.getElementById('show').innerHTML=h+":"+m+":"+s;
t = setTimeout("Timer()", 1000);
}
</script>
</head>
<body onload="Timer()">
<div id="show"></div>
</body></html>
setTimeout is used to delay a function/method execution. Then why it is being used in a real-time clock?
t = setTimeout("Timer()", 1000);
This part is confusing.
The clock is recursively calling itself, after the elapsed period of time.
Making a real-time clock is impossible in JS.
Because of how JS engines work, if you put Timer in a loop, to run for an infinite period of time, you'd never see the time update on the screen (as changes aren't drawn to the window until a function finishes and there's a gap in the program).
Also, inside that infinite-loop, it would be impossible to do anything else with the page (even closing it), because JS can only do one thing at a time, so it can't listen to any of the user's clicking until it's done with this loop.......
So that's what the setTimeout is for.
Timer is the function which acts as the clock.
Inside of the Timer function, at the end when all of the work is done, it's telling setTimeout to wait 1 second (1000ms) and then to call a function called Timer.
Timer just so happens to be the same function. But setTimeout doesn't know that, and doesn't care.
The t in this case is largely useless. setTimeout will return a number -- like taking a number at the doctor's office.
If, before you go through with it, you decide to back out, you can call clearTimeout(t); and it'll skip over that call (in this case, it would stop calling the clock).
There are a few bad-practices in here, that I figure I should mention, so that you can try not to copy them in your own practice.
First:
Pass setTimeout a reference to a function, and not a string...
var runThisFunction = function () { console.log("It's the future!"); },
time_to_wait = 250;
// DON'T DO THIS
setTimeout( "runThisFunction()", 250 );
// DO THIS
setTimeout( runThisFunction, 250 );
The difference is that setTimeout will run that string through eval, which can be a huge security concern depending on what you're trying to do.
The second problem is setting a random global variable, t... ...and hoping to use that as a solution.
First, in a couple of years, JS engines are going to start yelling at people for doing that stuff. Second, it's a huge hole, because any part of any app on that page could then overwrite t, or you could be relying on t somewhere else in your script, but every 1000ms, it gets written over with a new number.
Instead, they probably should have used a Timer.start(); and Timer.stop(); setup.
Your code:
t = setTimeout("Timer()", 1000);
The first thing you should know is that it's considered bad practice to put the first parameter in a string -- it should be the function name, unquoted, and without brackets, like so:
t = setTimeout(Timer, 1000);
That aside, your question about why it's being used to display a clock:
The use of setTimeout() inside the Timer() function to call itself is a common Javascript pattern to get a function to be called repeatedly. setTimeout() itself only triggers the function to be called a single time, after the given period of time has elapsed, so for a repeating event it needs to be re-triggered every time.
Since the setTimeout call is inside the Timer() function, it won't be set until Timer() is called the first time by some other means. This is where the body onload comes in.
As you suspect, setTimeout() isn't an accurate method for guaranteeing that a function will be called after exactly a given amount of time. Javascript is not multi-threaded, so any event handlers that are triggered must wait for any other code that is running at the same time. If something else is running slowly, this may cause your timer not to be triggered at exactly the moment it wants to be.
However, this isn't really a problem for your clock , because the clock is setting itself to the actual system time rather than relying on the setTimeout loop to keep itself in sync; the setTimeout loop is simply being used to make sure the display is updated (approximately) once a second. If it isn't actually quite exactly once a second, it doesn't really matter.
I hope that helps explain things a bit better.
When the Timer() function is called, it schedules itself to be run again one second later. The end result is once every second, Timer() updates the show element with the current time. (I have no idea why it's assigned to t, unless t is used in some other code on the page.)
The line starts The function again after one second.

javascript - detect end of chained functions?

Today I'm working on a pet project using chained function calls, and I'm curious how I might detect when the last function in the chain is executed. For example:
func1('initial data').func2().func3().func4();
And after func2-4 have finished working on 'initial data' I'd like to detect when func4 is done. Since func4() isn't always the last function in the chain, aka it could end at .func3() or .func5() for example, or I could mix my function calls up depending on what I'm trying to do, I'm trying to think of a way to detect no more function calls are being done but I'm not getting very far.
You can't.
Besides, if they are not chained:
var v = func1('initial data');
v = v.func2();
v = v.func3();
v = v.func4();
What would you consider to be the last function? Every function is the last function in it's own chain, but if you finalise something after each step, that won't work.
Just make a function that you call last to finalise the process.
The traditional approach is to put whatever you want done after the final function on the next line:
func1('initial data').func2().func3().func4();
allFunctionsDone();
;)
You can write the sequencer, which will help you to do this for you. Instead of executing direct calls, shift the names of the functions and call them one by one. Something like this
executeSequence(func1('init_dat'),[
'func2',
'func3',
'func4'
]);

Categories

Resources