学完Deferred这一章,这里个人做个小总结吧。
$.Deferred()返回一个deferred对象,内部还包含着状态state, 以及promise对象。这个deferred对象中包含着三个Callbacks对象,分别管理done, fail, progress这三个状态。并且deferred对象向外提供done, fail, progress, resolve, reject等接口,用来改变内部对应的Callbacks对象的状态。由于Callbacks对象都是once memory结构的(progress的只是memory结构),所以只要通过resolve/reject触发一次,那么Callbacks对象就被固定了,同时deferred对象内部的state也被确定了。当然,这时候还是可以通过done/fail来继续给Callbacks对象添加订阅对象,只是添加的时候就会立马执行(这就是memory的作用),执行完以后Callbacks内的list又会被清空(这是once的作用),这样就不能再通过resolve/reject触发了。
由于memory的作用,所以就算先resolve/reject,后done/fail还是可以正常运行的。因为memory对保存resolve/reject时的参数。
个人认为then是整个Deferred中最精妙的设计。这里以一个例子说明:$.Deferred().then(fn1).then(fn2)
首先$.Deferred()会生成一个deferred对象,这里暂且称为A。然后调用then方法,并且参数是fn1,此时会返回一个新的deferred对象,这里暂且称为B。并且在B对象生成后,会将函数fn1通过A.done/fail/progress添加到A的Callbacks的队列中。所以当A对象被确定后,会运行fn1函数。同时,当fn1函数运行完以后,如果fn1函数返回一个promise对象,那么这时候会创建一个新的deferred对象,叫C,并且将对象B的resolve/reject方法添加到C的Callbacks队列中,等待对象C的触发。如果fn1函数返回一个普通的结果,那么这时候就直接触发B对象。
上述的操作就在A和B之间形成了一个链式调用,并且如果fn1返回promise对象,则会等待fn1运行结束以后再触发B。当然,后面也可以继续添加then(fn2)。过程和4一样。
学到了,
不错不错哦