How to prevent “Stop running this Script” in browsers?

匿名 (未验证) 提交于 2019-12-03 01:33:01

问题:

I have an ASP.NET MVC page that has JQuery Editable Datatable that has 14 columns. I have a button (Apply No Findings)to do Client side calcultions snd apply for all Rows in that table.

When we click on this button, after applying calculations for every 4 Rows, it is displaying this "Stop Running Script" Message.

I verified the settings. In the Internet Options, Advanced tab, "Disable Script debugging(Internet Explorer)" option is Checked. And "Display a Notification about Script Error" is Unchecked.

I am using Internet Explorer 8. I Now it does not happen on IE9. But this being the server, we cannot upgrade to IE9.

I did the Research and tried these two options and nothing worked.

Example(1): http://www.codeproject.com/Tips/406739/Preventing-Stop-running-this-script-in-Browsers

Example(2): http://www.picnet.com.au/blogs/guido/post/2010/03/04/how-to-prevent-stop-running-this-script-message-in-browsers/

Anyone had this isse and any suggestions are highly appreciated.

This is actual code that is throwing the Script Message:

for(i < iTotalRecords;i++)        {                var row = oTableAuditLines.fnGetData(i);              oTableAuditLines.fnUpdate("NF",i,1);              UndoHCPCS(row,i);             UndoHCPCSModCodes(row,i);             UndoLineUnitCount(row,i);             oTableAuditLines.fnUpdate("", i, 6); //Reset Denial Reason Code             UndoNonCoveredCharges(row,i);             CalculateAmountPaidAtLine(row,i);             CalculateEstimatedRecoveryAmountAtLine(row,i);       }       UpdateSummaryLine();       UpdateSummaryLineReasonCode(); 

By referring sample code in Example(2), I changed the code as below and I am still getting the Script message:

//This function is to avoid Script Running Message

  RepeatingOperation = function(op, yieldEveryIteration)    {     var count = 0;     var instance = this;     this.step = function(args)    {       if (++count >= yieldEveryIteration)    {         count = 0;         setTimeout(function() { op(args); }, 1, [])         return;         }       op(args);     };   };    function ApplyNoFindings()   {      var i = 0;     var ro = new RepeatingOperation(function()       {         var row = oTableAuditLines.fnGetData(i);              oTableAuditLines.fnUpdate("NF",i,1);              UndoHCPCS(row,i);             UndoHCPCSModCodes(row,i);             UndoLineUnitCount(row,i);             oTableAuditLines.fnUpdate("", i, 6); //Reset Denial Reason Code             UndoNonCoveredCharges(row,i);             CalculateAmountPaidAtLine(row,i);             CalculateEstimatedRecoveryAmountAtLine(row,i);       if (++i < iTotalRecords)       {          ro.step();       }        else       {          UpdateSummaryLine();         UpdateSummaryLineReasonCode();      }        }, 100);      ro.step(); 

}

What am i doing wrong here?

回答1:

The problem is javascript is single-threaded, so if there is a function that takes too long to complete, this function could cause the UI not responding. Therefore, the browser will warn the user about long running script by displaying the message: "Stop running this script". The solutions to this problem are:

  • Optimize your code so the function does not take so long.
  • Use setTimeout to break the function execution into many pieces that are short enough.

Example code pattern:

var array = []; //assume that this is a very big array var divideInto = 4; var chunkSize = rowCount/divideInto; var iteration = 0;  setTimeout(function doStuff(){   var base = chunkSize * iteration;   var To = Math.min(base+chunkSize,array.length);   while (base < To ){       //process array[base]       base++;   }   iteration++;   if (iteration < divideInto)       setTimeout(doStuff,0); //schedule for next phase },0); 

The solution you take in your Example(2) is correct, but there is a problem in your code. That's the setTimeout does not run. Try changing your code like this:

RepeatingOperation = function(op, yieldEveryIteration)    {     var count = 0;     var instance = this;     this.step = function(args)      {            op(args);         if (++count <= yieldEveryIteration)         {                    setTimeout(function() { instance.step(args); }, 1, [])                 }         };      }; 

Modify your function ApplyNoFindings(), try this:

if (++i > iTotalRecords)   {      UpdateSummaryLine();     UpdateSummaryLineReasonCode();  }   

instead of:

if (++i < iTotalRecords)       {          ro.step();       }        else       {          UpdateSummaryLine();         UpdateSummaryLineReasonCode();      }   

Note: not tested, just give you an idea how it should work



回答2:

Despite another answer already accepted I want to place here general information for developers who will have this problem in feature:

By this link you can find information how to fix this from user side http://support.microsoft.com/kb/175500 - user can add one Registry key.

Also you can find there information about when this "Running slow" message appears:

By default, the key does not exist. If the key has not been added, the default threshold limit for the time-out dialog box is 5,000,000 statements for Internet Explorer 4 and later versions.

As you see slowness measured in javascript statements, not in time.



回答3:

You can also consider HTML 5 workers

A web worker is a JavaScript running in the background, without affecting the performance of the page. When executing scripts in an HTML page, the page becomes unresponsive until the script is finished. A web worker is a JavaScript that runs in the background, independently of other scripts, without affecting the performance of the page.

Creating a new worker is simple. All you need to do is call the Worker() constructor, specifying the URI of a script to execute in the worker thread, set the worker's Worker.onmessage property to an appropriate event handler function.

var myWorker = new Worker("my_task.js");  myWorker.onmessage = function (oEvent) {   console.log("Called back by the worker!\n"); }; 

Alternatively, you could use addEventListener() :

var myWorker = new Worker("my_task.js");  myWorker.addEventListener("message", function (oEvent) {   console.log("Called back by the worker!\n"); }, false);  myWorker.postMessage(""); // start the worker. 

You can see more details at: https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!