IE displays Script error on recursive function - javascript

Hy guys!
I have a recursive function that takes time to perform. The IE is "thinking" that function is like a loop with no end.
What should I do to make IE don't show the error?
Thks guys!

You cannot, it is a functionality in most browsers to give the user a way out if he visits a webpage with javascript that ties up his cpu for too long and thus kills the browser.
The only way around it, is to performance optimize your code so it goes faster :)
I am assuming the "error" look like this, otherwise my answer is wrong:

Javascript in your browser runs in a single thread. If you have some kind of code running (recursive or otherwise) that does not yield to the browser every now and then, the browser will pause the script and ask the user whether they want to stop the code or continue. If this didn't happen there would be no way for the user to regain control (if you like your long-running code is running on the same thread as the UI, that is, the webpage). That's why ajax calls are structured in such a way that your code does not wait (that is, block) for the result, but instead a callback function is, well, called back with the results.
So how do you yield in a long-running piece of code? Several ways (ajax is one example) but the most popular is to use setTimeout in some way. Unfortunately it's just not that easy to explain how to use it without knowing what you are doing exactly. Any small examples I could give would be artificial.
So the strict answer to your question is "rewrite your code into execution chunks such t
hat there's no one chunk that takes a long time to execute".

Related

Why is javascript execution time different every time?

If the code is exactly the same every time it runs, why didn't it use exact same amount of execution time?
For example, code as simple as:
console.time();
console.timeEnd();
would yield different result every time I run it.
To understand why it is so, first of all you should know JS works in conurrency model. There is event loop in Javascript which is responsible for executing the JS code. So this reference will definitely help to answer this question.
There are lots of things happening that use memory in your computer while you have your browser open and your script is running. Those things affect how much memory your browser has access to. The more memory your browser has available at that time, the faster your script will run.

While true difference between browser and a compiled program on the OS

Today I watched a colleague of my program a small game in Python on his Raspberry Pi. The game engine ran by using a while(true) or infinite loop. I myself use a websocket program in PHP that uses while(true). In these examples a infinite while loop is used which doesn't cause the program to become unresponsive. Without it, it wouldn't work properly. However in JavaScript we need to avoid a infinite loop at all costs. When a loop becomes infinite the browser hangs and becomes unresponsive.
My question: What is the difference between a infinite loop running in a compiled Python program and a infinite loop written in JavaScript running in a browser?
The difference is that the JavaScript runs on the browser's UI thread (preventing it from pumping normal OS messages like paint), whereas the Python program doesn't have a UI, and thus it doesn't matter if the main thread is hogged by your code.
You're still blocking the main thread either way, but in different contexts.
The main diffrence between the Python and the JavaScript code is that the Python code takes care of updating the UI, whereas the JS code just loops it's game logic and is therefore preventing the browser from updating it's view.
When you make a game, you usually put your in a loop where the first call goes to the game logic to update positions, player health, cat count and something like this. After that, you call a render method so that your updated content is processed as a picture and send to the screen. Then you start again. In JavaScript, you omitt the call to the render function and therefore the browser's UI never updates.
This has nothing to do with threading, but in a language like Pyhton (and many others) you can separate the game logic and the rendering so that when your logic is taking a while to do it's cat repositioning the programm is still able to update your screen (with the same, non-updated content over and over but that's another topic).
TL;DR The JavaScript blocks the rendering process of the Browser, whereas the Python loop explicitly calls the rendering function for it's UI.
For JS you should use setInterval(function, time), as #RĂșnarBerg noted.
EDIT: #mouser noted that you can also use web workers, which seem to be a html5 approach to multi-threading in JS. It may be worth a look if you are developing a game in JS, especially since it's supported in all major browser according to w3schools.
In Python, your loop probably looks like this:
while true:
TakeInput()
DoStuff()
So each iteration of the loop does something, and it keeps doing that forever.
In JavaScript, the input usually comes from the browser. If your JavaScript code is looping forever, the browser never gets a chance to let your code know new input has arrived.
You could write JavaScript code like this:
while (true) {
x = input('Give me input!');
// Process x
alert(result);
}
which would approximate the Python code, but that's not the way JavaScript usually works, and side-steps the browser all together.
Javascript has asynchronous runtime, meaning that your code doesn't usually have to wait for other parts to continue. You can run an infinite non-blocking loop with setInterval(fn, time) which executes the function fn at an interval of time milliseconds.

Is there is any way to call a function when an infinite loop or browsser hangs in javascript?

hi i m working a project which have huge javascript code sometimes javascript code executes automaticaly and hangs browser with message "kill this page" in chrome is there is any way to track the error .like calling calling a function when infinite loop arrives or browsser hangs like that .please give me some suggestion about debugging javascript code plz.
There is no way of doing what you wish inside javascript.
However you can use a tool like DynaTrace Ajax Edition to trace cpu usage in the browser to identify what is happening.
Infinite loop can be caused in many different bad programming logic, and there is no reliable logic to detect in every case. So I highly doubt if any programming language or IDE would offer any reliable infinite loop detection.
What you saw was basically a runtime detection based on how long script execution has taken before the browser could update and refresh the UI.
Sometimes this kind of long running JavaScript could be caused by infinite loop, but many times they are just big loops or loops that perform too much work that makes UI unresponsive.
Because JavaScript is not multi-thread, therefore to avoid the later case above, you could consider breaking the loops into small units of work, once a unit is finished, don't run the next unit, but instead call the next unit of work with setTimeout with a small time delay (such as 250ms). This would give the browser a chance to breath and update UI, and unmark your script as "long-running" script.
You may also use logging such as Firebug Logging to log the loops with enough values that help you find out if those loops are indeed infinite loops.

JavaScript and single-threadedness

I always hear that JavaScript is single-threaded; that when JavaScript is executed, it's all run in the same global mosh pit, all in a single thread.
While that may be true, that single execution thread may spawn new threads, asynchronousy reqeiving data back to the main thread, correct? For example, when an XMLHttpRequest is sent, doesn't the browser create a new thread that performs the HTTP transaction, then invoke callbacks back in the main thread when the XMLHttpRequest returns?
What about timers--setTimeout and setInterval? How do those work?
Is this single-threadedness the result of the language? What has stopped JavaScript from having multi-threaded execution before the new Web Workers draft?
XMLHttpRequest, notably, does not block the current thread. However, its specifics within the runtime are not outlined in any specification. It may run in a separate thread or within the current thread, making use of non-blocking I/O.
setTimeout and setInterval set timers that, when run down to zero, add an item for execution, either a line of code of a function/callback, to the execution stack, starting the JavaScript engine if code execution has stopped. In other words, they tell the JavaScript engine to do something after it has finished doing whatever it's doing currently. To see this in action, set multiple setTimeout(s) within one method and call it.
Your JavaScript itself is single-threaded. It may, however, interact with other threads in the browser (which is frequently written with something like C and C++). This is how asynchronous XHR's work. The browser may create a new thread (or it may re-use an existing one with an event loop.)
Timers and intervals will try to make your JavaScript run later, but if you have a while(1){ ; } running don't expect a timer or interval to interrupt it.
(edit: left something out.)
The single-threadedness is largely a result of the ECMA specification. There's really no language constructs for dealing with multiple threads. It wouldn't be impossible to write a JavaScript interpreter with multiple threads and the tools to interact with them, but no one really does that. Certainly no one will do it in a web browser; it would mess everything up. (If you're doing something server-side like Node.js, you'll see that they have eschewed multithreading in the JavaScript proper in favor of a snazzy event loop, and optional multi-processing.)
See this post for a description of how the javascript event queue works, including how it's related to ajax calls.
The browser certainly uses at least one native OS thread/process to handle the actual interface to the OS to retrieve system events (mouse, keyboard, timers, network events, etc...). Whether there is more than one native OS-level thread is dependent upon the browser implementation and isn't really relevant to Javascript behavior. All events from the outside world go through the javascript event queue and no event is processed until a previous javascript thread of execution is completed and the next event is then pulled from the queue given to the javascript engine.
Browser may have other threads to do the job but your Javascript code will still be executed in one thread. Here is how it would work in practice.
In case of time out, browser will create a separate thread to wait for time out to expire or use some other mechanism to implement actual timing logic. Then timeout expires, the message will be placed on main event queue that tells the runtime to execute your handler. and that will happen as soon as message is picked up by main thread.
AJAX request would work similarly. Some browser internal thread may actually connect to server and wait for the response and once response is available place appropriate message on main event queue so main thread executes the handler.
In all cases your code will get executed by main thread. This is not different from most other UI system except that browser hides that logic from you. On other platforms you may need to deal with separate threads and ensure execution of handlers on UI thread.
Putting it more simply than talking in terms of threads, in general (for the browsers I'm aware of) there will only be one block of JavaScript executing at any given time.
When you make an asynchronous Ajax request or call setTimeout or setInterval the browser may manage them in another thread, but the actual JS code in the callbacks will not execute until some point after the currently executing block of code finishes. It just gets queued up.
A simple test to demonstrate this is if you put a piece of relatively long running code after a setTimeout but in the same block:
setTimeout("alert('Timeout!');", 5);
alert("After setTimeout; before loop");
for (var i=0, x=0; i < 2000000; i++) { x += i };
alert("After loop");
If you run the above you'll see the "After setTimeout" alert, then there'll be a pause while the loop runs, then you'll see "After loop", and only after that will you see "Timeout!" - even though clearly much longer than 5ms has passed (especially if you take a while to close the first alert).
An often-quoted reason for the single-thread is that it simplifies the browser's job of rendering the page, because you don't get the situation of lots of different threads of JavaScript all trying to update the DOM at the same time.
Javascript is a language designed to be embedded. It can and has been used in programs that execute javascript concurrently on different operating threads. There isn't much demand for an embedded language to explicitly control the creation of new threads of execution, but it could certainly be done by providing a host object with the required capabilities. The WHATWG actually includes a justification for their decision not to push a standard concurrent execution capability for browsers.

IE does not render changes while javascript script is running

I have a rather long running javascript code which adds a new "div" element to the document. It looks like in IE this change is being rendered only after the script is finished, which is not the case in FF.
Any idea how to make it work ? This script is actually supposed to run forever, kind of "main loop".
I would avoid using a persistent, ever-running script. If you need things to happen on a recurring schedule, periodically, then use Window.SetTimout/SetInterval. Otherwise, use events. There are numerous JS frameworks out there, such as Mootools, that make it easy to implement you're own custom events, which should eliminate the need for a "main loop".
http://mootools.net/
Don't use a script that constantly runs, JavaScript is not meant to be used like that. Use event-based code or scheduler-based code. I'm pretty sure if you have a constantly running script you will trigger a "some scripts on this page are taking an abnormally long amount of time to run" type of popup from some browsers. It should not be expected behavior.
This script is actually supposed to run forever, kind of "main loop".
You can't do that in JavaScript. While you keep control of the thread of execution, the browser can't do anything, like check for clicks. In this state the browser is unresponsive and can appear to have crashed. Eventually most browsers will pop up a warning saying the script isn't playing nice, and give the user a button to click to unceremoniously kill it off.
Instead, you must return control to the browser as normal and ask it to call you back a bit later by using window.setTimeout(function, delay) for a one-off or window.setInterval(function, period) to have it keep calling back every so often. Any state you want to maintain over calls will have to be stored in global or instance variables.
The reason for this behavior is the manner in which Internet Explorer re-paint the window on DOM changes; in other words it is due to reflow.
Unless I'm mistaken, IE will queue the reflow tasks, and will act on them when the script thread has finished executing. If you write code to never halt the thread, reflow will never happen and you will never visualize the changes in DOM.
The alternative method that others have suggested - using window.setTimeout() and window.setInterval() is viable and will help in resolving the problem due to brief pauses available to the browser to act on the reflow tasks.
You will find this related SO question on when reflow occurs to be useful.

Categories

Resources