UPDATE (5 July 2013):
I've learned much since I originally asked this question. In one of the comments below it was suggested that I re-approach the task and find a way to solve it without risk of blocking the UI. I said it was impossible, the function must run as is. I don't actually remember what I was trying to accomplish with the function, but I'm certain that the commenter was right, and I was wrong. If you stumble upon this question and are in a similar situation as I was, then consider very seriously the possibility that your approach is flawed.
You might also want to look into web workers.
Here is where you can expect them to work.
Original Question:
Rather than get overly specific to my problem, I'll keep this generic so other people who stumble upon this can find it useful.
I have a function that accepts one parameter, a string. If the string is short the function runs fine and completes in a timely fashion. If, however, the string that's passed in is too long the script runs for a bit, then eventually times out and returns the browser's slow script dialog that allows the user to kill the script.
I would like to prevent that from happening so the script can continue to its terminus.
How can this be done?
A side note: If I can get this working, I would also like to make a status bar, similar to the one you see when loading gmail, appear so the user knows things are happening.
Thanks!
UPDATE (5 July 2013):
I've learned much since I originally asked this question. In one of the comments below it was suggested that I re-approach the task and find a way to solve it without risk of blocking the UI. I said it was impossible, the function must run as is. I don't actually remember what I was trying to accomplish with the function, but I'm certain that the commenter was right, and I was wrong. If you stumble upon this question and are in a similar situation as I was, then consider very seriously the possibility that your approach is flawed.
You might also want to look into web workers.
Here is where you can expect them to work.
Original Question:
Rather than get overly specific to my problem, I'll keep this generic so other people who stumble upon this can find it useful.
I have a function that accepts one parameter, a string. If the string is short the function runs fine and completes in a timely fashion. If, however, the string that's passed in is too long the script runs for a bit, then eventually times out and returns the browser's slow script dialog that allows the user to kill the script.
I would like to prevent that from happening so the script can continue to its terminus.
How can this be done?
A side note: If I can get this working, I would also like to make a status bar, similar to the one you see when loading gmail, appear so the user knows things are happening.
Thanks!
Share Improve this question edited May 5, 2014 at 17:38 Tyler Biscoe asked Jul 6, 2011 at 14:42 Tyler BiscoeTyler Biscoe 2,4223 gold badges22 silver badges33 bronze badges 3- 5 I think you need to fix your function so it doesn't take so long. – lonesomeday Commented Jul 6, 2011 at 14:44
- 1 Then you need to do it somewhere other than in the browser. Perhaps you could port the function to whatever server-side language you are suing. – lonesomeday Commented Jul 6, 2011 at 14:48
- 1 I'll try felipe's suggestion first, then if I must I'll pass it to the server. Thanks for the tips. – Tyler Biscoe Commented Jul 6, 2011 at 14:52
5 Answers
Reset to default 6You can try not blocking the UI completely and make it run "in another thread" with setTimeout
.
window.setTimeout(function() { ... code ... }, 0);
I say "in another thread" because there is no real multi-thread in JS, and here is an nice article about it
EDIT: (To make this answer more up-to-date with web technologies)
You can also use HTML 5 Web Workers depending on the browser you are targeting
No way you can disable that behavior in any browser by script. Imagine the impact, disable that feature and call a while(1)
. Pretty bad.
It's on you to create code which does not block the browser for "too long". There are a ton if best-practice patterns. I always recommend to try to break down your algorythm into smaller chunks. Combine that with a runaway-timer and a loop which makes sure that any operation does not run for longer than 100ms (for instance).
var sequence = ['foo', 'bar', 'baz', 'base', 'ball', 'hello', 'world', '100k more'],
start = Date.now();
setTimeout(function _worker() {
do {
var element = sequence.shift();
// do something with element
} while( sequence.length && (Date.now() - start < 100) );
if( sequence.length )
setTimeout(_worker, 25);
}, 25);
Unless your code is really aggressively bad or malicious, this almost always happens exclusively in IE 9 and below when an innocent script has loops that take too long to execute or an AJAX call is made to a slow server or there's lots of data to be returned and it exceeds allowed limits.
So, you could get your users to follow Microsoft's official fix for this issue here if it really bothers them: http://support.microsoft.com/kb/175500 If they run this Microsoft FixIT patch which increases their default MaxScriptStatements from the default 5,000,000 statements to the maximum allowed (represented by hex value 0xFFFFFF which is equal to 4,294,967,295 total statements of execution) it should fix the problem unless as I mentioned, the code was particularly bad or in need of refactoring.
In summary, your options are thus:
best solution - fix your script... breakup loops and/or halt recursion after N number executions, and ensure AJAX requests are asynchronous not synchronous where possible, especially in loops
alternative hack - use HTML5 WebWorkers, but better use WebWorker detection first to see if your browser supports them, and use a WebWorker shim library like this or this if not supported
mediocre hack - setTimeout with a real script execution Timer and breaking loops up into iterations, could have edge cases that cause worse problems...
terrible hack - ActiveX registry writing, better use proper browser detection plus feature detection
best workaround - Microsoft FixIT patch, if its just a small subset of users, have Tech Support send them to the official Microsoft FixIT page (or do it yourself) which more reliably adds the appropriate registry entries to increase script execution count
you can try few things:
- running function asynchronously using setTimeout
- making your function sleep every now and then to stop blocking UI for long time(hell if it's that slow, let it run a bit longer)
- use javascript workers as alternative to setTimeout, here's some quick googling for you: http://ejohn.org/blog/web-workers/
To remove the warning:
function setMaxScriptStatements(){
var WshShell = new ActiveXObject("WScript.Shell");
WshShell.RegWrite ("HKCU\\Software\\Microsoft\\Internet Explorer\\Styles\\MaxScriptStatements", 1107296255, "REG_DWORD");
}