jquery中的 deferred之 then (二)
例:
var def = $.Deferred();
var prs1 = def.then(function (val) {
var result = val + "_123"
console.log(result);// 0_123
return result;;
});
var prs2 = prs1.then(function (val) {
var result = val + "_234"
console.log(result);// 0_123_234
return result;
});
var prs3 = prs2.then(function (val) {
var result = val + "_345"
console.log(result);// 0_123_234_345
return result;
});
def.resolve("0");
核心源码分析:
then: function( /* fnDone, fnFail, fnProgress */ ) {
var fns = arguments;
return jQuery.Deferred(function (newDefer) { //20170620 huanhua 当调用 jQuery.Deferred(参数) 参数不为空的时候,参数必须是 包含 $.Deferred()对象参数的函数
//if ( func ) { func.call( deferred, deferred );} 详见下面这段代码。
jQuery.each(tuples, function (i, tuple) {
var action = tuple[ 0 ],
fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
// deferred[ done | fail | progress ] for forwarding actions to newDefer
deferred[ tuple[1] ](function() {
var returned = fn && fn.apply(this, arguments);
//20170620 huanhua 如果then方法传递的参数 [fnDone, fnFail, fnProgress],其中的函数如果返回的是 Defferred对象。
if (returned && jQuery.isFunction(returned.promise)) {
//20170620 huanhua 此时注册的 done/fail/progess 就是传入的 Defferred对象已经注册好了的对象
//20170624 huahua returned是一个 deferred,在 fn 里面,必须要调用 deferred.resolve/deferred.reject/deferred.notify
//否则不会 触发 newDefer.resolve/newDefer.reject/newDefer.notify
returned.promise()
.done( newDefer.resolve )
.fail( newDefer.reject )
.progress( newDefer.notify );
} else {
newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
}
});
});
fns = null;
}).promise();
},
里面最核心的一段代码,如下这段代码能看懂基本就看懂了 then了:
deferred[ tuple[1] ](function() {
var returned = fn && fn.apply(this, arguments);
//20170620 huanhua 如果then方法传递的参数 [fnDone, fnFail, fnProgress],其中的函数如果返回的是 Defferred对象。
if (returned && jQuery.isFunction(returned.promise)) {
//20170620 huanhua 此时注册的 done/fail/progess 就是传入的 Defferred对象已经注册好了的对象
//20170624 huahua returned是一个 deferred,在 fn 里面,必须要调用 deferred.resolve/deferred.reject/deferred.notify
//否则不会 触发 newDefer.resolve/newDefer.reject/newDefer.notify
returned.promise()
.done( newDefer.resolve )
.fail( newDefer.reject )
.progress( newDefer.notify );
} else {
newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
}
});
首先我们看一个案例:
var Person = function () {
var listdo = [];
var parValue = "";
this.fire = function (value) {
parValue = value;
for (var xh in listdo) {
listdo[xh](value);
}
};
this.do = function (fn) {
var prs = new Person();
if (typeof fn === "function") {
listdo.push(fn);
}
listdo.push(function () { prs.fire(parValue); });
return prs;
}
};
var person1 = new Person();
person1.do(function (val) { alert("孩子们:" + val); })
.do(function (val) { alert("孙子们:" + val); })
.do(function (val) { alert("重孙们:" + val); });
person1.fire("操练起来!!!");
这段代码中有一个祖孙的链式关系,通过闭包来实现的,分析见图2。
图2:
这个思路很重要,也是 then 实现的核心思想。
在then的源代码中有这么一段代码:
// deferred[ done | fail | progress ] for forwarding actions to newDefer
deferred[ tuple[1] ](function() {
deferred[tuple[1]]就是在给 deferred[done|fail|progess]添加执行的方法
newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
这段代码就是添加的执行链式中下一个对象的方法。returned或者arguments就是传递到链式中下一个要执行的对象中的方法的参数。
如果这些都看懂了,then的实现原理就明白了,实现了一个按照 then添加的先后顺序进行执行的功能。
jquery中的 deferred之 then (二)的更多相关文章
- jQuery中的Deferred和promise
promise:http://www.alloyteam.com/2014/05/javascript-promise-mode/ 1 jQuery 中的 Deferred 和 Promises : ...
- javascript 学习笔记之JQuery中的Deferred对象
Deffered是Jquery中的一个非常重要的对象,从1.5版本之后,Jquery中的ajax操作都基于Deffered进行了重构,这个对象的处理模式就像其他Javascript框中的Promise ...
- jQuery中的常用内容总结(二)
jQuery中的常用内容总结(二) 转载请注明地址: http://www.cnblogs.com/funnyzpc/p/7571993.html 前言 距离上次博客更新已经有二十来天了(●′ω`●) ...
- jQuery中的deferred对象和extend方法
1⃣️deferred对象 deferred对象是jQuery的回调函数解决方案,它是从jQuery1.5.0版本开始引入的功能 deferred对象的方法 (1) $.Deferred() 生成一个 ...
- 深入理解jQuery中的Deferred
引入 1 在开发的过程中,我们经常遇到某些耗时很长的javascript操作,并且伴随着大量的异步. 2 比如我们有一个ajax的操作,这个ajax从发出请求到接收响应需要5秒,在这5秒内我们可以 ...
- jquery中的 deferred之 when (三)
先来看使用案例: var def1 = $.Deferred(); var def2 = $.Deferred(); var def3 = $.Deferred(); var def4 = $.Def ...
- jQuery 中的 Deferred 和 Promises(转)
转自:http://www.css88.com/archives/4750/comment-page-1 看前首先了解:Promises/A规范,具体可以看这里,http://www.css88.co ...
- jquery中的 deferred之 deferred对象 (一)
案例: var def=$.Deferred(); console.log(def);//答案见 图1 图1: deferred就是一个有这些方法的对象. 看源码分析: Deferred: funct ...
- jQuery中Animate进阶用法(二)
Step Type: Function( Number now, Tween tween )每个动画元素的每个动画属性将调用的函数.这个函数为修改Tween 对象提供了一个机会来改变设置中得属性值. ...
随机推荐
- Where 与 Having
WHERE在数据分组前进行过滤,HAVING在数据分组后过滤. HAVING可以对检索(或计算)出的结果过滤,WHERE则不行. WHERE.聚合函数.HAVING在from后面的执行顺序:WHERE ...
- spring事务详解(三)源码详解
系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...
- HanLP中文分词Lucene插件
基于HanLP,支持包括Solr(7.x)在内的任何基于Lucene(7.x)的系统. Maven <dependency> <groupId>com.hankcs.nlp&l ...
- 模板语言 自定义函数simple_tag
模板语言自带的一些处理函数:通过管道符来处理 帮助方法:{{ item.event_start|date:"Y-m-d H:i:s"}} 转换成日期时间型{{ bio|trunc ...
- Windows下安装Spark环境
根据博客总结 https://blog.csdn.net/nxw_tsp/article/details/78281533 需要的安装软件可以在网盘下载: 链接:https://pan.baidu.c ...
- Extjs相关知识
1.链接 1.1.零散知识链接 https://blog.csdn.net/zhaojianrun/article/details/70141071 https://www.cnblogs.com/p ...
- 知识点:Mysql 数据库索引优化实战(4)
知识点:Mysql 索引原理完全手册(1) 知识点:Mysql 索引原理完全手册(2) 知识点:Mysql 索引优化实战(3) 知识点:Mysql 数据库索引优化实战(4) 一:插入订单 业务逻辑:插 ...
- RabbitMQ tutorial
一.安装RabbitMQ RabbitMQ是一套开源(MPL)的消息队列服务软件,是由 LShift 提供的一个 Advanced Message Queuing Protocol (AMQP) 的开 ...
- Linux基础之常用命令整理(二)
Linux系统启动流程 bios(找到启动介质) --> mbr(找到boot loader 512B 446引导信息 64分区信息 2 标志位 ) -->grub(选择操作系统或者内核 ...
- maven教程全攻略
maven教程全攻略 我们在开发项目的过程中,会使用一些开源框架.第三方的工具等等,这些都是以jar包的方式被项目所引用,并且有些jar包还会依赖其他的jar包,我们同样需要添加到项目中,所有这些相关 ...