可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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