同步jquery $ .ajax没有锁定IE?

花了一点时间试图实现这个并且有一个我觉得在firefox中工作得很好的解决方案,但是当在IE中测试发现使用async:false导致浏览器被锁定(停止响应并且已经冻结)通话时间。

要求基本如下。 我提供了一系列用户可以检查的复选框。 在特定时间,我调用我的函数’selectedSeriesData()’,该函数用于向我的服务一个接一个地发送请求以获取所请求的数据。 我特别选择使用sync,以便在执行方法时可以向浏览器输出状态消息和警告。

例如。 “加载数据1/3”,然后“加载数据2/3”,“加载数据3/3”

当然,我现在知道这会锁定某些浏览器,因此IE中的体验不仅会锁定浏览器,而且我尝试显示的任何消息都不会显示。 是否有任何类型的简单doEvents,例如我可以在每次ajax调用之后调用的操作,或者只是重构我的ajax调用的问题。 如果是这样的话,根据我的要求提供任何实施建议?

以下是代码的简化摘录以供参考。

function selectedSeriesData() { var seriesData = []; var index = 0; $.each($("input[name='idCheckBox']:checked"), function () { var id = $(this).val(); $("#loadingMessage").text("Loading " + id + "..."); $.ajax({ type: 'POST', async: false, url: '', dataType: 'json', data: { Id: id }, success: function (data) { seriesData[index] = data; index++; }, error: function (xhr, ajaxOptions, error) { $("#warnings ul").append('
  • A communication error occured while attempting to load data for the series.
  • '); } }); } }); return seriesData; }

    您可以使用jQuery Deferred对象继续使用异步请求,然后在所有结果完成后“加入”结果。

     function selectedSeriesData(cb) { var reqs = []; $("#loadingMessage").text("Loading..."); $("input[name='idCheckBox']:checked").each(function () { var id = $(this).val(); var req = $.ajax({ type: 'POST', url: '<%: loadSeriesDataPath %>', dataType: 'json', data: { Id: id }, error: function(xhr, ajaxOptions, error) { $("#warnings ul").append('
  • A communication error occured while attempting to load data for the series.
  • '); } }); reqs.push(req); }); $.when(reqs).done(function() { cb($.makeArray(arguments)); }); }

    现在您只需将回调传递给您的函数,然后只要所有结果都成功完成,它就会收到一个包含AJAX请求所有结果的数组。

    注意: $.when上的文档并不是很清楚它是否接受包含延迟的单个数组。 万一它不起作用尝试$.when.apply($, reqs)而不是$.when.apply($, reqs) $.when(reqs)

    我认为我问题的最佳答案是……你做错了。 我没有任何运气与$ .when建议(也许是由于我的理解),所以我自己想出了以下答案。

    基本上,使用回调来实现一种递归排队。 对你们所有人来说这听起来很明显,但对我来说这是新手,我认为那里经验丰富的jqueryer会同意我的实施(如果我做得对,请告诉我!)

    首先,不是循环我的复选框并发出ajax请求,而是建立一个请求数组。 这消除了从原始方法返回我的结果的需要,并开始一个方法执行链,从而导致期望的结果。

     function selectedSeriesData() { var requests = []; $.each($("input[name='somethingCheckBox']:checked"), function () { var id = $(this).attr('value'); var request = { id: id }; requests.push(request); }); loadRequests(requests); } 

    从请求数组中,启动调用loadRequests,初始化递归回调实现以从我的服务加载数据。

     function loadRequests(requests) { $("#loader").show(); var seriesData = []; loadRequestAt(requests, 0, seriesData); } 

    调用的递归方法是loadRequestAt,它跟踪请求数组,加载此itteration的特定索引,以及调用方法时添加的seriesData。 匿名方法成功用于构建我的seriesData,用于报告错误的错误,以及用于开始下一次请求迭代的完成,或者如果已完成所有请求,则将结果呈现给屏幕。

     function loadRequestAt(requests, loadAtIndex, seriesData) { var currentRequest = requests[loadAtIndex]; $("#loadingMessage").text("Loading " + currentRequest.id + "..."); $.ajax({ type: 'POST', url: '<%: loadSeriesDataPath %>', dataType: 'json', data: { Id: currentRequest.id }, success: function(data) { seriesData.push(data); }, error: function(xhr, ajaxOptions, error) { $("#warnings ul").append('
  • A communication error occured while attempting to load ' + currentRequest.id'.
  • '); }, complete: function() { var nextIndex = loadAtIndex + 1; if (nextIndex < requests.length) { loadRequestAt(requests, nextIndex, seriesData); } else { $("#loader").hide(); renderResults(seriesData); } } }); }

    重要经验教训。 使用AJAX(异步JavaScript和XML)时,请使用异步调用。 请使用提供的匿名回调方法来实现渐进式排队function(我确信有一个可接受的名称,但我不确定)。 希望我的学习步骤能帮助那些不熟悉jquery和ajax调用的人。 谢谢!