好了,那么如果then方法中的回调函数的返回值是一个非deferred对象呢?那么它就将这个返回值带上,直接触发then方法自行创建的deferred对象的相关事件,从而,如果then方法后有then方法,也就关联了。
好了,promise.then方法解决就算基本完毕。
四、思考
细细品来,大家有没有发现,其实promise.then就是通过作用域链,利用jQuery.Deferred中的变量deferred来关联父deferred的。如果,你还记得数据结构中的单链表,有没有发觉似曾相识呢,作者在这里通过jQuery.Deferred这个工厂构建每个deferred,然后利用作用域链相互关联,就如同单链表一样。
因此,借助这一思想,我们就一同模拟一个非常简单的Deferred,称作SimpleDef。主要作用就是每次我们执行SimpleDef函数,它都会返回一个构建好的simpleDef对象,该对象里面包含了三个方法done、then以及fire:
--done就如同add方法般,将done里的参数添加到它父simpleDef列表list中,并返回父simpleDef对象;
--then就是将其参数func添加到父SimpleDef对象的列表list中,并返回一个新SimpleDef对象;
--fire就是触发对应simpleDef对象的list列表里的所有函数。
实现代码如下:
function SimpleDef(){ var list = [], simpleDef = { done: function(func){ list.push(func); return simpleDef; }, then: function(func){ list.push(func); return SimpleDef(); }, fire: function(){ var i = list.length; while(i--){ list[i](); } } }; return simpleDef; }
测试代码如下:
var def = SimpleDef(); var then1 = def.done(function(){ console.log('self1-done1'); }).done(function(){ console.log('self1-done2'); }).then(function(){ console.log('self2-then1'); }).done(function(){ console.log('self2-done1'); }); def.fire();//=>self2-then1 self1-done2 self1-done1 console.log('xxxxxxxxxxxxxxxxxxxx'); then1.fire();//=>self2-done1