I'm repeatedly coming into troubles with Internet Explorer's "This script is taking too long to run, would you like to continue?" messages. I am wondering if anyone is aware of a clever way to trick the JS engine into keeping quiet? Based on some searching I did, I found that the engine monitors states it thinks potentially could be infinitely looping, so I thought maybe I could add some logic to change up the execution every once in a while to fool it into leaving it alone, but no luck. I also tried breaking up a longer loop into several shorter ones, but that hasn't helped. Specifically the code that is currently causing issues is the expansion of nodes in a tree structure. The code is looping over the current nodes and expanding each. It's a trivial thing to write in Javascript, but I can't allow these timeout errors, so I think my only option might be to request pre-expanded view data via AJAX. I'm currently working in a DEV environment with a small(ish) data set and I know this will not fly in other environments. Has anyone managed to suppress these warnings?
views:
105answers:
7Have you tried making it output something every once in a while? It might be that it just checks for output and if there hasn't been any in x seconds, it assumes you're in an infinite loop.
If outputting works, you could try something like adding and then immediately deleting something really small (like an empty <span>
).
How about spacing it using a series of events. So a loop occurs sends an event, listener to event triggers and does a loop. etc..?
Using setTimeout
A good way is simulating threaded execution using setTimeout()
function calls. This requires splitting your whole processing into smaller parts and queueing them one after another. Timeouts can be set quite close to each other but they will run one by one when each of them finishes execution.
Why not break your function into a series of steps and queue them up using jQuery?
A very common solution for this problem is to use setTimeout function. The way you do it is that you separate the process into smaller pieces a then execute those pieces one after another using the setTimeout function. I think this http://www.julienlecomte.net/blog/2007/10/28/ should help you. There is also another option introduced by HTML5 WebWorkers. This new standard should allow you to execute long running tasks in a separate thread and then report any results in a callback. You can read about it here robertnyman.com/2010/03/25/using-html5-web-workers-to-have-background-computational-power/ Unfortunatelly, it is not supported by IE according to html5demos.com/
I think the timeout is more based on the number of statements than timing or heuristics. You could go a long way to increasing the amount your code can handle before triggering the warning by optimizing your code for simple things -- especially if you are using helper APIs on another library like jQuery. For example, change this:
$.each(arr, function(value) {
// do stuff
});
to this:
for (var i = 0, l = arr.length; i < l; i++) {
var value = arr[i];
// do stuff
}
Another easy one -- cache access to fields. If you have two instances of "foo.bar", store the result in a variable and use it, wherever that makes sense.
Obviously I have no idea what your code looks like, but I bet you could do a lot to improve it as these little things really add up when you're talking about this timeout problem.
I managed to do this by using prototypes Function#defer method, which is essentially the same as using the setTimeout method. Thanks everyone!