2012-04-20 132 views
3

花了一点时间去实现这一点,有一个解决方案,我认为作品相当不错,在Firefox,但在IE浏览器中进行测试时发现,使用异步:假导致浏览器被锁定(停止响应和apprears有冰冻)在通话期间。

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

例如。 “加载数据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: '<%: loadSeriesDataPath %>', 
       dataType: 'json', 
       data: { 
        Id: id 
       }, 
       success: function (data) { 
        seriesData[index] = data; 
        index++; 
       }, 
       error: function (xhr, ajaxOptions, error) { 
        $("#warnings ul").append('<li>A communication error occured while attempting to load data for the series.</li>'); 

       } 
      }); 
     } 
    }); 
    return seriesData; 
} 
+0

你是什么意思的“锁”? – OptimusCrime 2012-04-20 08:59:56

+0

OptimusCrime,当我说锁,我的意思是浏览器实际上停止响应,并且只有在循环完成执行后才开始响应。因此,对于使用IE的最终用户来说,它看起来像浏览器崩溃了。 – Arkiliknam 2012-04-20 09:02:12

+0

你能提供jsFiddle的例子吗? – tarmaq 2012-04-20 09:04:19

回答

1

我认为我的问题的最佳答案是...你做错了。如果有人建议(也许这是由于我对它的理解),我没有任何运气,所以自己提出了以下答案。

基本上,使用回调来实现一种递归排队。这听起来对你们来说听起来很明显,但它对我来说是新的,我认为那里有经验的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。匿名方法成功用于构建我的系列数据,用于报告错误的错误,以及完成最重要的用于开始下一次请求传输或完成所有请求时,将结果呈现在屏幕上。

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('<li>A communication error occured while attempting to load ' + currentRequest.id'.</li>'); 
     }, 
     complete: function() { 
      var nextIndex = loadAtIndex + 1; 
      if (nextIndex < requests.length) { 
       loadRequestAt(requests, nextIndex, seriesData); 
      } else { 
       $("#loader").hide(); 
       renderResults(seriesData); 
      } 
     } 
    }); 
} 

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

1

您可以使用jQuery Deferred objects使用异步请求保留,然后选择“加入”的结果时,所有的人都已经完成。

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('<li>A communication error occured while attempting to load data for the series.</li>'); 

      } 
     }); 
     reqs.push(req); 
    }); 
    $.when(reqs).done(function() { 
     cb($.makeArray(arguments)); 
    }); 
} 

现在,您只需通过一个回调到您的函数,然后将接收只要他们都成功完成包含来自AJAX请求的所有结果的阵列。

注:$.when该文档是不是,如果它接受包含deferreds单一阵列中真正明确。如果它不工作尝试$.when.apply($, reqs)而不是$.when(reqs)

+0

这听起来太棒了。我会马上检查出来! – Arkiliknam 2012-04-20 10:04:39

+0

延期对象没有任何运气,但并非100%确定它是否适合我的问题。我确实想出了一个我现在发布的asyn解决方案,如果社区同意或不同意,我会感兴趣。 – Arkiliknam 2012-04-20 16:36:36