所谓异步队列,就是在还未执行首个函数的时候,就已经把队列的顺序规定好了,然后按照自己规定的顺序有顺序的执行。前面一篇博客已经见识了异步队列的强大之处,其实异步队列与队列有着相似的用途,只不过异步队列的功能更为强大。
要实现异步队列,必须要提前知道这个队列到底是什么顺序,而要实现队列的顺序,有两种思路,一是利用数组,而是利用链表。
本例用单链表实现,数组其实也差不多,大家感兴趣可以下来自己写写。
既然是单链表,那么数据结构应该是下面这样:
var Deferred=function(fn){ if(!(this instanceof Deferred)){ return new Deferred(fn); } this.fn=fn; this.nextDeferred=null; }
之所以写了if条件,完全是因为在js中,我讨厌new的做法,这里稍微影响了性能,更为妥当的做法是利用一个函数返回新的实例,记住:条件判断语句越少越好,既提高了可读性,也增加了扩展性,性能有时候也会提高。这里暂时先这样写。
然后依次添加下面三个原型方法:
Deferred.prototype.fire=function(){ this.fn.apply(this,arguments); } Deferred.prototype.then=function(fn){ return this.nextDeferred=Deferred(fn); } Deferred.prototype.next=function(){ var nextDeferred=this.nextDeferred; nextDeferred&&nextDeferred.fire.apply(nextDeferred,arguments); }
第一个方法是执行本函数,then是添加下一个任务,next是用在函数体中,手动调用下一个任务。
我们来看看是怎么调用的:
var test=Deferred(function(a){var defer=this;setTimeout(function(){console.log(a++);defer.next(a);},1000);});test.then(function(a){var defer=this;setTimeout(function(){console.log(a++);defer.next(a);},1000);}).then(function(a){var defer=this;setTimeout(function(){console.log(a++);defer.next(a);},1000);});test.fire(1);
看看结果:
每次都是隔一秒才显示下一个数字。
本次就简单的实现了以下异步队列,其实更倾向于jq的队列,不管怎样掌握这种职责链模式,是对自己有帮助的,谢谢大家!