Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Javascript

Preventing ‘Stop running this script’ in Browsers

5.00/5 (1 vote)
19 Jun 2012CPOL2 min read 30.5K   452  
A Sample with a Quick Explanation

 Download TestWeb.zip

 Introduction 

On all major versions of IE you may run into this error - "This page contains a script which is taking an unusually long time to finish. To end this script now, click Cancel". This is beyond irritating especially when the code is live and is affecting customers. Microsoft has a fix for it, but obviously we cannot ask a customer to do this. 

Background

What we are going to try and do is create a "for loop" that builds an array. But consisting of 100000 items. 

Using the code

I've include a sample project - it's always so much easier when you can play with the code yourself. Have fun!

Before we get into the code, Kudos completely to Guido Tapia for his code and implementation.

I've modified the code and made it slightly mode applicable to me, and also to external readers who do not have the context of the code. There was also some bugs which I ironed out. But again, Kudos to him.  

C++
 // Make an Object
RepeatOperation = function (anonymousOperation, whenToYield) {
    var count = 0;
    return function () {
        if (++count >= whenToYield) {
            count = 0;
            setTimeout(function () { anonymousOperation(); }, 100);
        }
        else {
            anonymousOperation();
        }
    }
};  

Above we create a simple Object called "RepeatOperation". In it we have to arguments. One will be our (or your) anonymous operation (work that needs to get done). The second argument, will be the when to yield, or when to fire the Time Out. 

In side the function, is a basic count to determine where we are in the "process". Every time our anonymous operation is called it will come back in here and increment count. When it reaches the yield count, it will then set the Time Out letting the Browser know that this is no an infinite loop.   

C++
// Implementation
var i = 0;
var myArray = new Array(noInArray);
var yieldAfter = 100;
var noInArray = 100000;
var ro = new RepeatOperation(function () {  // Anonymous function which is our work that we need 2 
    myArray[i] = i * 1;
    if (++i < noInArray) {
        ro();
    }
    else {
        // Finished with Operation
        $("#txtBox").val("Completed Operation and no Browser Warning!");
    }
}, yieldAfter);

// Let's begin
ro();

Now we get to the meat - remembering that state is maintained across the calls due to that little thing called "closure". For a better understanding of this implementation, look at this, it's a wonderful read

Moving along, we create an instance of RepeatOperation, passing in our "operation" as well as when to yield (after x number of iterations). We then begin by calling RepeatOperation through ro(); Remembering in light of closures, this will now call the "return" function found in RepeatOperation, and where it will validate where we are, and set the Time Out if necessary.

The code will continuously call itself back, and while doing so, build the array that we need or get the work done that we need. When done, it will finish and add the text to our "txtBox".  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)