周梦康 发表于 2014-05-21 3081 次浏览

场景:有一个任务队列,每个任务的耗时都稍微有点长。任务队列就是下面的数组idArr,假如其中有4个元素,每个任务执行需要耗时3秒,那么把下面的代码放到执行任务的页面之后就需要等待12秒才能刷出来,不然会一直在等待。

var id = '{$id}';
var idArr = id.split(',');//[1,2,3,4]
var url = '{:U('CollectArticle/Collect/index')}';
//过程化执行,同步执行
function doCollect(){
    while(idArr.length){
        var webid = parseInt(idArr.pop());
        $.ajax({
            type:'POST',
            url:url,
            data:{id:webid},
            async: false,
            dataType:'json'
        }).always(function(data) {
                console.log( data.info );
        });
    }
}
doCollect();

就算我设置为了在dom加载完毕之后再执行,也还是不行。

我的笨办法,我想既然不能这样,那么我就setTimeout来执行。首先我把时间设置为10毫秒,似乎没有效果,但是我把时间改成了100毫秒就OK了。 最终发现:用setTimeout的办法之后,虽然是在页面加载完毕之后开始执行;但是在所有ajax循环执行完毕之前,页面也还是“锁死的”。每个ajax返回的信息不能及时反馈到页面上来。还是得选择异步,其实发现异步也挺好。

    var id = '{$id}';
    var idArr = id.split(',');
    var url = '{:U('CollectArticle/Collect/index')}';
    function doCollect(){
        while(idArr.length){
            var webid = parseInt(idArr.pop());
            $.ajax({
                type:'POST',
                url:url,
                data:{id:webid},
                async: false,
                dataType:'json'
            }).always(function(data) {
                    console.log( data.info );
            });
        }
    }
    //doCollect();
    setTimeout(function(){
        doCollect();
    },100);

为了追求更高端的方法,问下下我的“顾问团”,他说可以使用promise来实现ajax异步顺序执行。给我贴了个demo,先保存到这,对于promise这样的高阶方法,一直没玩明白。

;(function ($, window, document, undefined) {
  var

  result = function (func, args) {
    return function () {
      return $.when(func.apply(null, args));
    };
  },

  // realize promises one by one
  sync = function (tasks, fnAlways) {
    var i, l, task, func, prom;

    prom = $.Deferred().resolve().promise();

    for (i = 0, l = tasks.length; i < l; i += 1) {
      task = tasks[i];
      func = task.shift();
      prom = prom.then(result(func, task)).always(fnAlways);
    }

    return prom;
  };

  // do job
  var id = '{$id}';
  var idArr = id.split(',');
  var url = '{:U('CollectArticle/Collect/index')}';
  var tasks = [];

  while (idArr.length) {
    var webid = parseInt(idArr.pop(), 10);
    tasks.push([$.ajax, {
      type: 'POST',
      url: url,
      data: {id:webid},
      dataType: 'json'
    }]);
  }

  sync(tasks, function (data) {
    console.log(data.info);
  });
}).call(this, jQuery, this, this.document);

👇 下面是我的公众号,高质量的博文我会第一时间同步到公众号,给个关注吧!

评论列表