【问题标题】:How to call ajax function sequentially如何顺序调用ajax函数
【发布时间】:2013-11-20 06:47:46
【问题描述】:
    function loadGraphInSeq(startDate,endDate,calcSubStart,calcSubEnd){
        var graphName=new Array();
        $('section div.graph_box').each(function(){
            if ($(this).css('display')=='block') {
                graphName.push($(this).attr('id'));
            }
        });
        for (index=0;index<graphName.length;index++) {
            switch (graphName[index]) {
                case 'allquery':
                    break;
                case 'alwazinc':
                    alwayzincreasing(calcSubStart,calcSubEnd,startDate,endDate);
                    break;
                case 'segment':
                    ajaxCallingSegment(startDate,endDate,calcSubStart,calcSubEnd);
                    break;
                case 'answeredresponse':
                   ajaxCallingSegmentRespDay(startDate,endDate,calcSubStart,calcSubEnd);
                    break;
                case 'segmentresponse':
                   ajaxCallingSegmentRespHours(startDate,endDate,calcSubStart,calcSubEnd);
                    break;
                case 'lessthanDonut':
                    ajaxCallinglessthanDonut(startDate,endDate,calcSubStart,calcSubEnd,'total');
                    ajaxCallinglessthanDonut(startDate,endDate,calcSubStart,calcSubEnd,'latency');
                    ajaxCallinglessthanDonut(startDate,endDate,calcSubStart,calcSubEnd,'delivery');
                    break;
                case 'carrierPie':
                    ajaxCallingCarrierPie(startDate,endDate,calcSubStart,calcSubEnd);
                    break;
            }

        }
    }

让我解释一下,我有显示图表的类 .graph_box。当我更改调用 loadGraphInSeq 的日期并且我想按顺序加载图表时,这些 div 的顺序会发生变化,即,除非加载一个图表,否则不应调用其他函数。 switch 语句中的函数调用该函数来加载图形。目前此功能一次性加载所有功能。 graphName 堆叠了所有需要加载的图(未隐藏的)名称。

【问题讨论】:

  • 在 for 循环中调用 ajax 函数不会保证您的执行顺序。我认为您需要从数组(pop 数组)中调用第一个函数,为 ajaxRequest 提供回调函数,然后再次在回调 pop 数组中调用下一个函数。这样您就可以确保所需的顺序。
  • 是的,我想到了使用 callback() 函数,但我不知道如何使用。我使用了 foreach 函数,但这没有帮助。你能给我举个例子吗?
  • 试试这个链接可能对你有帮助stackoverflow.com/questions/19572306/…
  • @Yevgeniy.Chernobrivets 使用 jQuery promise 可以保证正确的顺序。我会尽快发布答案。还没有使用 jQuery 的 promise 实现,听说它不是“标准的”,所以必须先检查文档(当我有时间的时候)
  • 用“async: false”试过了吗?

标签: javascript jquery ajax


【解决方案1】:

这似乎是实现我想要的很长的路要走,我已将函数 loadGraphInSeq 更改为仅返回函数名称,并且在每个 ajax 函数之后调用该函数 loadGraphInSeq 以获取要调用的下一个函数的名称,我加载函数名根据 div 位置使用

$('section div.graph_box').each(function(){
                                if ($(this).css('display')=='block') {
                                    graphName.push($(this).attr('id'));
                                }
                            });

graphName 是全局的,按顺序存储 div 的名称。然后在 ajax 函数的每一端调用 LoadGraphInSeq 以调用下一个函数调用。

function loadGraphInSeq(startDate,endDate,calcSubStart,calcSubEnd,graphNametoCall){
                switch (graphNametoCall) {
                    case 'allquery':
                        return(loadGraphInSeq(startDate,endDate,calcSubStart,calcSubEnd,graphName[graphname++]));
                    case 'ajaxCallingAlwazIncr':
                        ajaxCallingAlwazIncr(calcSubStart,calcSubEnd,startDate,endDate);
                        return(loadGraphInSeq(startDate,endDate,calcSubStart,calcSubEnd,graphName[graphname++]));
                    case 'segment':
                        return 'ajaxCallingSegment';
                    case 'answeredresponse':
                        return 'ajaxCallingSegmentRespDay';
                    case 'segmentresponse':
                        return 'ajaxCallingSegmentRespHours';
                    case 'lessthanDonut':
                        return 'ajaxCallinglessthanDonut';
                    case 'carrierPie':
                        return 'ajaxCallingCarrierPie';
                    default:
                        return 0;
                }
        }

这是我在每个函数之后写的代码

 funcToCall=loadGraphInSeq(startDate,endDate,calcSubStart,calcSubEnd,graphName[graphname++]);
                     if (funcToCall!=0) {
                        var strParam = "startDate,endDate,calcSubStart,calcSubEnd";
                        var funcCall = funcToCall + "(" + strParam + ");";
                        eval(funcCall);
                    }

【讨论】:

  • 您不应该使用 eval,好消息是您不必这样做。删除第一个 var 语句并将 eval 语句替换为:window[funcToCall](startDate,endDate,calcSubStart,calcSubEnd);
【解决方案2】:

您可以使用 $.get 返回的延迟对象(或任何其他 jQuery 的 XHR 方法)。

使用您的代码,我更新了示例。 asynch 和 synch 函数都应该返回一个 Promise。异步(XHR 请求)将自动解决或使您手动执行的同步失败(包括在示例中)

//your synchronous function
function alwayzincreasing(calcSubStart,calcSubEnd,startDate,endDate){
  var deferred = $.Deferred();  
  deferred.resolve("to be passed to the next function");
  //do stuff here (non asynch);
  //return a promise
  return deferred.promise();
};
function ajaxCallingSegment(startDate,endDate,calcSubStart,calcSubEnd){
  //make sure you return the return value of $.ajax or $.get or $.post
  return $.get("url");//do not put unsuccess or anthing like that here
}
function loadGraphInSeq(startDate,endDate,calcSubStart,calcSubEnd){
  var graphName=new Array(),fn=[],i=-1,len,p,d,e;
  $('section div.graph_box').each(function(){
    if ($(this).css('display')=='block') {
      graphName.push($(this).attr('id'));
    }
  });
  for (index=0;index<graphName.length;index++) {
    switch (graphName[index]) {
      case 'allquery':
        break;
      case 'alwazinc':
        fn.push(function(){
          return alwayzincreasing(calcSubStart,calcSubEnd,startDate,endDate);
        });
        break;
      case 'segment':
        fn.push(function(){
          return ajaxCallingSegment(startDate,endDate,calcSubStart,calcSubEnd);
        });
        break;
      case 'answeredresponse':
        fn.push(function(){
          return ajaxCallingSegmentRespDay(startDate,endDate,calcSubStart,calcSubEnd);
        });
        break;
      case 'segmentresponse':
        fn.push(function(){
          return ajaxCallingSegmentRespHours(startDate,endDate,calcSubStart,calcSubEnd);
        });
        break;
      case 'lessthanDonut':
        fn.push(function(){
          return ajaxCallinglessthanDonut(startDate,endDate,calcSubStart,calcSubEnd,'total');
        });
        fn.push(function(){
          return ajaxCallinglessthanDonut(startDate,endDate,calcSubStart,calcSubEnd,'latency');
        });
        fn.push(function(){
          return ajaxCallinglessthanDonut(startDate,endDate,calcSubStart,calcSubEnd,'delivery');
        });
        break;
      case 'carrierPie':
        fn.push(function(){
          return ajaxCallingCarrierPie(startDate,endDate,calcSubStart,calcSubEnd);
        });
        break;
    }
  }
  len = fn.length;
  d=jQuery.Deferred();
  p = d.promise();
  while(++i<len){
    p.then(fn[i]);
  }
  p.then(function(){
    console.log("done");
  },
  function(){
    console.log("Failed");
  });
  d.resolve();
}

【讨论】:

  • @AbhishekPatidar 我已更新示例以反映您的情况。有 2 个示例函数显示了要返回的内容以确保承诺堆叠有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多