我有一个ASP.NET MVC页面,其中包含14列的JQuery Editable Datatable。 我有一个按钮(应用无结果)来进行客户端计算并适用于该表中的所有行。
当我们点击此按钮时,在每4行应用计算后,它将显示此“停止运行脚本”消息。
我验证了设置。在“Internet选项”的“高级”选项卡中,“禁用脚本调试(Internet Explorer)”选项已选中。并且“显示有关脚本错误的通知”未选中。
我正在使用Internet Explorer 8.我现在不会在IE9上发生。但这是服务器,我们无法升级到IE9。
我做了研究并尝试了这两个选项,没有任何效果。
示例(1): http://www.codeproject.com/Tips/406739/Preventing-Stop-running-this-script-in-Browsers
任何人都有此事,我们非常感谢任何建议。
这是抛出脚本消息的实际代码:
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();
通过参考示例(2)中的示例代码,我更改了以下代码,我仍然收到脚本消息:
//此函数用于避免脚本运行消息
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();
}
我在这里做错了什么?
答案 0 :(得分:11)
问题是javascript是单线程的,所以如果有一个函数 需要太长时间才能完成 ,这个函数可能会导致UI没有响应。因此,浏览器将通过显示以下消息警告用户长时间运行的脚本:“停止运行此脚本”。这个问题的解决方案是:
setTimeout
将函数执行分解为很多足够短的部分。示例代码模式:
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);
您在示例(2)中采用的解决方案是正确的,但代码中存在问题。那是 setTimeout无法运行 。尝试更改您的代码:
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, [])
}
};
};
修改您的function ApplyNoFindings()
,试试这个:
if (++i > iTotalRecords)
{
UpdateSummaryLine();
UpdateSummaryLineReasonCode();
}
而不是:
if (++i < iTotalRecords)
{
ro.step();
}
else
{
UpdateSummaryLine();
UpdateSummaryLineReasonCode();
}
注意:未经过测试,只需告诉您应该如何运作
答案 1 :(得分:4)
尽管已经接受了另一个答案,但我想在此处提供一般信息,供开发人员解决此问题:
通过此链接,您可以找到有关如何从用户端http://support.microsoft.com/kb/175500解决此问题的信息 - 用户可以添加一个注册表项。
此外,您还可以找到有关何时显示“运行缓慢”消息的信息:
默认情况下,密钥不存在。如果尚未添加密钥,则对于Internet Explorer 4及更高版本,超时对话框的默认阈值限制为 5,000,000个语句。
当你看到在javascript语句中测量的缓慢,而不是及时。
答案 2 :(得分:0)
您还可以考虑HTML 5工作人员
Web worker是在后台运行的JavaScript,不会影响页面的性能。 在HTML页面中执行脚本时,页面将变为无响应,直到脚本完成。 Web worker是一种在后台运行的JavaScript,与其他脚本无关,不会影响页面的性能。
创建新员工很简单。您需要做的就是调用Worker()构造函数,指定要在工作线程中执行的脚本的URI,将worker的Worker.onmessage属性设置为适当的事件处理函数。
var myWorker = new Worker("my_task.js");
myWorker.onmessage = function (oEvent) {
console.log("Called back by the worker!\n");
};
或者,您可以使用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.
您可以在以下位置查看更多详情: https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers