章节
问答
笔记
评论
占位
占位

Deferred源码剖析(上)

Deferred对接口的设计别出心裁,不是常规的直接定义的,我们可以看tuples这个数组的定义。

Deferred自身则围绕这三组数据进行更高层次的抽象

  ☑ 触发回调函数列表执行(函数名)

  ☑ 添加回调函数(函数名)

  ☑ 回调函数列表(jQuery.Callbacks对象)

  ☑ Deferred最终状态(第三组数据除外)

var tuples = [
  // action, add listener, listener list, final state
  ["resolve", "done", jQuery.Callbacks("once memory"), "resolved"],
  ["reject", "fail", jQuery.Callbacks("once memory"), "rejected"],
  ["notify", "progress", jQuery.Callbacks("memory")]
]

这里抽象出2组阵营:

1组:回调方法/事件订阅 

done、fail、progress

2组:通知方法/事件发布    

resolve、reject、notify、resolveWith、rejectWith、notifyWith

Tuples元素集,其实是把相同有共同特性的代码的给合并成一种结构,然后来一次处理。

jQuery.each(tuples, function(i, tuple) {
  //代码请看右边代码区域
})

对于Tuples的3条数据集是分2部分处理的:

第一部分将回调函数存入

promise[ tuple[1] ] = list.add;

其实就是给promise赋予3个回调函数。

promise.done = $.Callbacks("once memory").add
promise.fail = $.Callbacks("once memory").add
promise.progressl = $.Callbacks("memory").add

如果存在Deferred最终状态,默认会预先向doneList,failList中的list添加三个回调函数。

if (stateString) {
  list.add(function() {
    state = stateString;
  }, tuples[i ^ 1][2].disable, tuples[2][2].lock);
}

这里有个小技巧:

i ^ 1 按位异或运算符

所以实际上第二个传参数是1、0索引对调了,所以取值是failList.disable与doneList.disable。

通过stateString有值这个条件,预先向doneList,failList中的list添加三个回调函数,分别是:

doneList : [changeState, failList.disable, processList.lock]
failList : [changeState, doneList.disable, processList.lock]

  ☑ changeState 改变状态的匿名函数,deferred的状态,分为三种:pending(初始状态), resolved(解决状态), rejected(拒绝状态);

  ☑ 不论deferred对象最终是resolve(还是reject),在首先改变对象状态之后,都会disable另一个函数列表failList(或者doneList);

  ☑ 然后lock processList保持其状态,最后执行剩下的之前done(或者fail)进来的回调函数。

所以第一步最终都是围绕这add方法:

  ☑ done/fail/是list.add也就是callbacks.add,将回调函数存入回调对象中。

第二部分很简单,给Deferred对象扩充6个方法:

  ☑ resolve/reject/notify 是 callbacks.fireWith,执行回调函数;

  ☑ resolveWith/rejectWith/notifyWith 是 callbacks.fireWith 队列方法引用。

最后合并promise到Deferred。

promise.promise( deferred );
jQuery.extend( obj, promise );

所以最终通过工厂方法Deferred构建的异步对象带的所有的方法了,return内部的deferred对象了。

任务

?不会了怎么办
||

提问题

写笔记

截图
提交
||

请验证,完成请求

由于请求次数过多,请先验证,完成再次请求

加群二维码

打开微信扫码自动绑定

您还未绑定服务号

绑定后可得到

  • · 粉丝专属优惠福利
  • · 大咖直播交流干货
  • · 课程更新,问题答复提醒
  • · 账号支付安全提醒

举报

0/150
提交
取消
全部 精华 我要发布
全部 我要发布
最新 点赞
只看我的

手记推荐

更多

本次提问将花费2个积分

你的积分不足,无法发表

为什么扣积分?

本次提问将花费2个积分

继续发表请点击 "确定"

为什么扣积分?