IE does not render changes while javascript script is running - javascript

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.

Related

Multithreading javascript

I want to create a real thread which manages some operations in javascript.
After several search, i found 'Web Workers', 'setTimeout' or 'setInterval'.
The problem is that 'Web Workers' don't have access to global variables and therefore can't modify my global arrays directly (or i do not know how).
'setTimeout' is not really what i need.
'setInterval' sets my problem, however it is probably that after many times my operations could last longer. Therefore i am afraid that two interval overlaps.
Finally i need a infinite loop which executes a series of operations once after another. Does it exist or do I have to content myself with 'setInterval'? Is there an alternative with jQuery or other? If it is not, is what I can expect in the near future to see the developer make it available?
I'm going to assume you're talking about in a web browser.
JavaScript in web browsers has a single main UI thread, and then zero or more web worker threads. Web workers are indeed isolated from the main UI thread (and each other) and so don't have access to globals (other than their own). This is intentional, it makes both implementing the environment and using it dramatically simpler and less error-prone. (Even if that isolation weren't enforced, it's good practice for multi-threaded programming anyway.) You send messages to, and receive messages from, web workers via postMessage and the message event.
JavaScript threads (the main UI thread and any web workers) work via a thread-specific task queue (aka "job queue"): Anything that needs to happen on a JavaScript thread (the initial run of the code when a page loads, handling of an event, timer callbacks [more below]) adds a task to the queue. The JavaScript engine runs a loop: Pick up the next task, run it, pick up the next, run it, etc. When there are no tasks, the thread goes quiet waiting for a task to arrive.
setTimeout doesn't create a separate thread, it just schedules a task (a call to a callback) to be added to the task queue for that same thread after a delay (the timeout). Once the timeout occurs, the task is queued, and when the task reaches the front of the queue the thread will handle it.
setInterval does exactly what setTimeout does, but schedules a recurring callback: Once the timeout occurs, it queues the task, then sets up another timeout to queue the task again later. (The rules around the timing are a bit complex.)
If you just want something to recur, forever, at intervals, and you want that thing to have access to global variables in the main UI thread, then you either:
Use setInterval once, which will set up recurring calls back to your code, or
Use setTimeout, and every time you get your callback, use setTimeout again to schedule the next one.
From your description, it sounds as though you may be calling setInterval more than once (for instance, on each callback), which quickly bogs down the thread as you're constantly telling it to do more and more work.
The last thing is easy: webworker start their work when they get a message to (onmessage) and sit idle otherwise. (that's highly simplified, of course).
Global variables are not good for real multi-threading and even worse with the reduced thing JavaScript offers. You have to rewrite your workers to work standalone with only the information given.
Subworkers have a messaging system which you might be able to make good use of.
But the main problem with JavaScript is: once asynchronous always asynchronous. There is no way to "join" threads or a "wait4" or something similar. The only thing that can do both is the XMLHttprequest, so you can do it over a webserver but I doubt the lag that causes would do any good. BTW: synchronous XMLHttprequest is deprecated says Mozilla which also has a page listing all of the way where a synchronous request is necessary or at least very useful.

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.

How do you interrupt JS in browser?

What is the equivalent of pressing Ctrl+C in console, for Chrome and Firefox? While implementing various algorithms I often write some buggy (while) loop, in Javascript, that doesn't exit, makes the browser freeze. Reloading doesn't work, clicking little X for closing the tab doesn't do anything, and in a while (literally) I'm outta memory, system is swapping, and I'm leaving for a coffee break.
In Chrome, you can hit Shift+ESC (or right-click the title bar and open the Chrome task manager) and kill the process associated with the hung tab. This will work in cases where closing the tab would not.
The caveat is, sometimes Chrome will streamline several tabs into one process, and this will kill all the tabs associated with the process.
Another approach you can take to avoid while loops hanging the browser is to write code like this (you can take it out after testing):
var maxIterations = 100000;
while (foo) {
if (!maxIterations--) throw new Error('Max iterations hit, aborting.');
// do stuff
}
Right-click in Chrome's task manager and select the item on the bottom of the context menu to reveal a strange easter egg.
There is no such thing as a Ctrl + C for JavaScript. The browsers that executes JavaScript are usually protective of themselves. If any JavaScript hangs, they'll throw a dialog asking if the user wants to stop the JavaScript.
The timeout duration can usually be found in the browser's settings. You can find how to do it for FireFox here: http://kb.mozillazine.org/Dom.max_script_run_time
From what little insight I have into your ways of working, how I would proceed is:
Only execute the script on an event like button click. This would prevent script running onload
Chrome allows you to set break points in your js code in the scripts tab of developer tools
There is no real "interrupter" for running Javascript code in a browser. ECMAscript gets executed in the so called "UI thread", which means that all rendering stuff happens in the same queue that ECMAscript code gets executed.
That in turn means, an infinite loop in ECMAscript automatically hangs the whole browsers interaction.
The only way to avoid that is to write clear, clean code. If it happens anyway, most browsers realize that the UI thread is busy for too long and asks the user if he wants to cancel the running javascript processes. If you don't want to wait for that, your only choice is to kill the whole browser / tab process.
However, if you are aware that some part of your script does possibly cause an infinite loop, you can either set breakpoints manually in some sort of developer tools or you can insert the debugger; keyword directly into your script. That causes the javascript interpreter to halt at the current line and you have a chance to analyse the next code (while conditions for instance) and cancel the execution if it looks bad.

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 displays Script error on recursive function

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".

Categories

Resources