序列化函数调用

时间:2015-08-05 04:42:32

标签: javascript jquery

我有一个有一些价值的javaScript对象。我需要多次调用一个函数,因为对象具有值。查看代码snipet

for(var i=0; i < scroll["altscroll"]; i++){
    more_alt_leftajaxsearchcategory(0, 0, element=false, back = true);
}

被调用函数通过ajax方法加载一些元素并将其附加到正文。 问题是当循环执行时,函数被即时调用,但被调用函数返回的结果不是预期的顺序。例如,如果函数被调用3次,并且如果在最后一次调用时返回的结果的大小较小,那么在附加了另一个返回的结果之后,它首先附加在正文中。 我们可以序列化函数调用,以便在第一个函数完成之前不会调用另一个函数。 被调用的函数代码snipet:

var pageCount = 1;  
function more_leftajaxsearchcategory(locval,pageid, element, back){

    var offsetCount = pageCount * 10;
      var dataString = jQuery("#leftformid").serialize();   
      jQuery.ajax({
        url:"<?php echo admin_url('admin-ajax.php'); ?>",
        type:'POST',
        data: 'action=leftmenusearchcategory'+'&locationval='+locval+'&numb='+offsetCount+'&'+dataString,           
        beforeSend: function(){jQuery('body').append('<p class="overBck"><img alt="Loading..." src="<?php bloginfo('template_url'); ?>/images/ajax-loader.gif" style="margin-top:25%;"></p>'); },
        success:function(results, status)
        {       
                jQuery(".book_results").append(results);
                if(results == 'Sorry no results found. Please search again.'){
                    jQuery('.sidebar_loadMore').hide();
                    pageCount =1;
                }
                jQuery('.overBck').remove();
                 short_deals_attr();

        }

      });
    pageCount++;
}

我删除了不必要的代码。您还可以查看实际网站Bestofthebrunch

2 个答案:

答案 0 :(得分:1)

在这种情况下,我发现序列化函数调用的最佳方法是对前一个函数调用成功的递归调用。

more_alt_leftajaxsearchcategory(0, 0, element=false, back = true, scroll["altscroll"] -1);

并通过

更新了Ajax成功的被调用函数
 if(back && loadtimes > 0){
    more_alt_leftajaxsearchcategory(0, 0, element=false, back = true, loadtimes-1 ); 
}
像这样......

var pageCount = 1;  
function more_leftajaxsearchcategory(locval,pageid, element, back, times){
var offsetCount = pageCount * 10;
  var dataString = jQuery("#leftformid").serialize();   
  jQuery.ajax({
    url:"<?php echo admin_url('admin-ajax.php'); ?>",
    type:'POST',
    data: 'action=leftmenusearchcategory'+'&locationval='+locval+'&numb='+offsetCount+'&'+dataString,           
    beforeSend: function(){jQuery('body').append('<p class="overBck"><img alt="Loading..." src="<?php bloginfo('template_url'); ?>/images/ajax-loader.gif" style="margin-top:25%;"></p>'); },
    success:function(results, status)
    {       
            jQuery(".book_results").append(results);
            if(results == 'Sorry no results found. Please search again.'){
                jQuery('.sidebar_loadMore').hide();
                pageCount =1;
            }

            if(back && loadtimes > 0){
                more_alt_leftajaxsearchcategory(0, 0, element=false, back = true, loadtimes-1 ); 
            }

            jQuery('.overBck').remove();
             short_deals_attr();

    }

  });
pageCount++;
}

在此方法中,如果不关注先前调用的响应,则不会立即调用函数more_leftajaxsearchcategory。只有当第一个函数得到响应时才会调用该函数。

答案 1 :(得分:0)

你必须添加addtional param来传递一个在ajax完成它的工作时调用的回调,然后你就可以实现这样的事情。

我会使用随机长度的setTimeout作为ajax调用伪造:

var inserial = function(times) {
  var count = 0;
  function delay() {
    var cur = count;
    var length = Math.floor((Math.random() * 7) + 1) * 500;
    $('<div>').text('#' + cur + ' will complete in ' + length).appendTo($('body'));
    setTimeout(function() {
      // Somthing in success ajax callback.
      $('<div>').text('#' + cur + 'Done.').appendTo($('body'));
    
      // Then call it to start next ajax load.
      done();
    }, length);
    count++;
  }
  function done() {
    if (count === times) {
      $('<div>').text('All done').appendTo($('body'));
      return;
    }
    delay();
  }
  
  
  // Your function, which aceepts a callback function.
  delay();
};

inserial(5);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>

或者如果您喜欢接受新技术,请尝试使用Promise,这是一个ES2015功能,而已经有libs实现它,它可以让您轻松地同时启动所有加载过程,同时保持元素的顺序。 / p>

但你可能需要先了解它的想法,JavaScript Promises应该是一个好的开始。

var delay = function(id, cb) {
  var length = Math.floor((Math.random() * 7) + 1) * 500;
  $('<div>').text('#' + id + ' will complete in ' + length).appendTo($('body'));
  
  // Wrap you ajax into promise.
  return new Promise(function(resolve, reject){
      setTimeout(function() {
        
          // This will be called in ajax's success callback. 
          resolve(id);    
        
      }, length);  
  });
};

var i, arr = [];
// These function will all start to execute.
for (i = 0; i < 5; ++i) {
  arr[i] = delay(i);
}

// But their results will be guranteed to put in order.
var sequence = Promise.resolve();
arr.reduce(function(seq, item) {
  // 
  return seq.then(function() {
    // the promise return from delay will get the resolved id as parameter.
    return item;
  }).then(function(id) {
    
      // This is the commands in origin ajax's succes callback.
      $('<div>').text('#' + id + 'Complete.').appendTo($('body'));
  });
  
}, sequence);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.33.0/es6-shim.js"></script>