场景:有一个任务队列,每个任务的耗时都稍微有点长。任务队列就是下面的数组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);