“停止运行此脚本” - 用于大型AJAX请求的IE

时间:2009-12-18 21:07:40

标签: jquery ajax internet-explorer

我正在使用jQuery.getJSON(...)为稍大的数据集进行调用/进程响应。预计响应时间为几秒钟(有一个动画加载图形来安抚用户)。

总而言之,加载图形,响应,进程等在所有浏览器中都能正常运行。但是,在Internet Explorer(6/7/8)中,出现“停止运行此脚本”错误。如果允许继续,则脚本完成且没有问题。

$(document).ready(function() {
    $("#tree").treeview({ collapsed: true, animated: "slow" });
    $("#tree").hide();

    $("#loadingGraphic").fadeIn("slow");

    $.getJSON("mygenerichandler.ashx", function(data) {
        //manipulate data and add to treeview

        $("#loadingGraphic").fadeOut("slow", function() {
            $("#tree").slideDown("slow");
        });
    });
});

我意识到这个Internet Explorer有一个可以通过Windows注册表设置的首选项,但是,我很好奇其他开发人员如何在AJAX请求中处理预期的大或慢响应。

4 个答案:

答案 0 :(得分:4)

慢速脚本通知很可能不是针对实际请求,而是针对您运行的脚本来处理请求收到的数据。这也可能是解析JSON的jQuery代码。

如果您发布的脚本是“操纵数据”(即代码段中的注释部分),我们可能会帮助您优化它。

[编辑] 你是对的。你应该考虑延迟加载树。你通常有多少根节点?你可能有点运气appendTo()。要么一次构建整个HTML并执行大量appendTo(),要么使用未附加到DOM的中间div来累积节点,然后附加到主#tree元素。

var tempDiv = $('<div></div>');
for (var i in data) {
    tempDiv.append($(buildHierarchy(data[i]));
}
$("#tree").append(tempDiv);
$("#tree").treeview({ add: tempDiv }); //don't know if this works? Maybe tempDiv.children() ?

答案 1 :(得分:4)

我的猜测是,这不是数据的加载,也不是您在代码中处理的数据。我认为这是通过HTTP接收的JSON数据到Javascript对象的转换。

IE基本上使用eval()从字符串数据构建哈希。对于长字符串,这非常非常非常低效。我怀疑它背后有一个Schlemiel the Painter算法。我在一两年前完成了同样的事情,并通过从JSON字符串中删除未使用或冗余的数据来解决它。

如果你不能通过删除元素来缩短字符串,你可以尝试将服务器上的字符串分解为组件对象(如果你愿意的话,'pages')并获取它他们一个接一个。这样,您就不必为长字符串支付低效的处理税,而是处理几个短字符串。

答案 2 :(得分:2)

这不是问题的请求时间。请求是异步的,因此在等待响应时没有脚本运行。

正在处理结果的脚本耗时太长。将其发送到处理部分数据的函数,并使用计时器调用自身以将控件返回给浏览器片刻:

function handleData(data, offset) {
  // pick the next 1000 items or so:
  var size = Math.min(1000, data.length - offset);
  // process [offset .. offset+size-1] of the data
  // ...
  offset += size;
  if (offset < data.length) {
    window.setTimeout(function() { handleData(data, offset); }, 1);
  } else {
    $("#loadingGraphic").fadeOut("slow", function() {
      $("#tree").slideDown("slow");
    });
  }
}

用以下方式调用:

$.getJSON("mygenerichandler.ashx", function(data) {
  handleData(data, 0);
});

答案 3 :(得分:0)

您可以重构代码,以便在每次递归调用之前调用setTimeout(0),以便UI线程获得控制权并且可以响应。谷歌'setTimeout线程'获取更多信息。

您还可以将大型数据集拆分为由连续请求处理的块。在IE8中,您可能需要仔细检查是否正在使用本机JSON.parse()方法,因为它比JS实现更快。