jQuery(五): Deferred
jQuery(五): Deferred
有啥用
通常来说,js请求数据,无论是异步还是同步,都不会立即获取到结果,通常而言,我们一般是是使用回调函数再执行,而 deferred就是解决jQuery的回调函数方案,总的来说,deferred对象就是为了将某个回调函数延迟到某个时机再执行.
ajax链式写法:
//一般写法:
$.ajax({
url: '',
success: function(){},
error: function(){},
}) //deferred
$.ajax(url)
.done(function(){}) //相当于success
.fail(function(){})
指定同一操作的多个函数,允许添加多个函数
写法也很简单,直接添加在后面就可以了。$.ajax(url)
.done(function(){})
.fail(function(){})
.done(function(){})
为多个函数添加指定回调,可以为多个不同的函数添加同一个回调事件
$.when($.ajax(url),$.ajax(url2))
.done()
.fail()
为两个函数执行操作,如果都成功了就执行done中的回调,如果有一个失败或全部都失败,就执行fail中的回调
普通操作的回调
deferred允许任何操作都可以使用deferred对象的方法,指定回调函数var wait = function(de){
var test = function(){
console.log('开始');
de.resolve();
}
setTimeout(test, 3000);
return de;
} $.when(wait($.Deferred()))
.done(function(){
console.log('已完成')
})
.fail(function(){
console.log('失败')
})
注意: $.when()的参数只能是deferred对象。
咋处理
关于resolve && rejected
在上面的时候,会注意到一个resolve,并且会觉得这种链式写法很眼熟,且对promise有一个简单了解的话,大概就知道了。promise: 同样也是用于处理异步函数,将异步操作队列化处理 简单的promise
new promise (function(resolve,rejected){
resolve('成功')
})
.then(function(){}) promise.then 接受两个参数:
一、 resolve 代表成功时调用的函数
二、 rejected 代表失败时调用的回调
promise的三个状态值: pending(初始状态值), fulfilled(操作成功),rejected(操作失败)
$.deferred 同样也是有三个不同的状态:未完成,已完成,已失败,当状态处于已完成(resolve)下回自动调用done()中的回调函数,而resolve()就是人为将状态值修改为已完成,同理可证rejected();
总的来说,核心就是:根据不同的状态值调用回调。API
* $.Deferred()
* $.when()
* deferred.progress()
* deferred.promise()
* deferred.done()
* deferred.fail()
学习下
来看下jQ的源码是怎么处理的:
Deferred: function(func) {
var tuples = [
// action, add listener, callbacks,
// ... .then handlers, argument index, [final state]
["notify", "progress", jQuery.Callbacks("memory"),
jQuery.Callbacks("memory"), 2
],
["resolve", "done", jQuery.Callbacks("once memory"),
jQuery.Callbacks("once memory"), 0, "resolved"
],
["reject", "fail", jQuery.Callbacks("once memory"),
jQuery.Callbacks("once memory"), 1, "rejected"
]
],
state = 'pending',
// 延迟对象
deferred = {},
promise = {
state: function() {
return state
},
then: function(){},
promise: function(obj) {
return obj != null ? jQuery.extend(obj, promise): promise;
}
}
...
}
从代码来看,定一个了数组tuples,以及初始状态值。tuples存储了三个状态下的所需参数,来看下存储了写什么内容:
[状态, 对应的处理函数, 利用callbacks创建的回调队列, then方法的回调队列, index, 最终的状态值],
我们可以看到最终的状态值只有reject 和resolve才有。
ok,已经知道deferred的本质是根据不同的状态调用不同的方法,并且使用callbacks添加函数,那么把tuples遍历一下,生成队列;
源码:
tuples.forEach(function(tuple){
var list = tuple[2], // 获取到jQuery.callbacks返回,创建一个队列
stateString = tuple[5], //获取到最终状态描述
//promise[ progress | done | fail ] = list.add
promise[tuple[1]] = list.add;
// 如果最终状态值存在,即处于 reject|| resolve 状态下;
if (stateString) {
list.add(
function() {
state = stateString;
}
....
)
}
// 延迟对象状态 deferred.resolve()
//deferred[ 'resolve' | reject | notify] = function(){}
deferred[tuple[0]] = function() {
deferred[tuple[0]+"Width"](this === deferred ? promise : this, arguments);
return this;
}
//jQuery.callbacks.fireWith
//执行队列,调用处理函数,绑定执行时的上下文
deferred[tuple[0] + "With"] = list.fireWith;
})
promise.promise(deferred);
return deferred;
已经遍历生成了3个队列,并将三个状态方法挂载在了延迟对象上。
从代码中可以看出,在调用deferred[ reject | resolve]时,其实是调用了deferred[ rejectWith | resolveWith]方法,本质上是对callbacks.fireWith的调用,以用来执行添加的回调函数,同时设置函数的上下文。
并且可以看的到,deferred[proress | done | fail] 其实是copy了callbacks.add方法,将回调函数添加在了执行队列中。
另外关于对jQuery.deferred对象的详解,使用,https://www.cnblogs.com/chris-oil/p/8922770.html 这篇博文转载了阮大神的,可以瞅瞅
jQuery(五): Deferred的更多相关文章
- jQuery之Deferred源码剖析
一.前言 大约在夏季,我们谈过ES6的Promise(详见here),其实在ES6前jQuery早就有了Promise,也就是我们所知道的Deferred对象,宗旨当然也和ES6的Promise一样, ...
- jQuery的deferred对象详解(一)
最近一段时间,都在研究jquery里面的$.Deffered对象,几天都搞不明白,其中源码的运行机制,网上查找了相关的资料,<jQuery的deferred对象详解>阮一峰老师的文章,里面 ...
- [转] jQuery的deferred对象详解
jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...
- jQuery的deferred对象详解(转)
jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...
- jQuery的deferred对象详解 jquery回调函数
http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html jQuery的 ...
- jQuery的deferred对象详解(转载)
jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本.(由于无法转载,复制原文 .原文链接——原作者:阮一峰) 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5. ...
- 【转】jQuery的deferred对象详解
jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...
- jQuery的deferred对象详解(转)
jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...
- (转)jQuery的deferred对象详解
作者: 阮一峰 日期: 2011年8月16日 jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始 ...
随机推荐
- Django 购物车模板
url from django.contrib import admin from django.urls import path, re_path from django.urls import i ...
- VMWare中CentOS 7 配置 XShell连接
https://jingyan.baidu.com/article/363872ec796dfc6e4ba16f09.html http://www.cnblogs.com/iskylite/p/76 ...
- 渗透测试工具Nmap篇
Nmap是一款网络扫描和主机检测的非常有用的工具. Nmap是不局限于仅仅收集信息和枚举,同时可以用来作为一个漏洞探测器或安全扫描器.它可以适用于winodws,linux,mac等操作系统.Nmap ...
- CSS基础以及兼容IE方法
1 介绍一下标准的CSS的盒子模型?与低版本IE的盒子模型有什么不同的? 标准盒子模型:宽度=内容的宽度(content)+ border + padding + margin低版本IE盒子模型:宽度 ...
- python总结七
1.lpython是python语言的lisp前端,它类似于普通的lisp语言,他会被直接编译成字节码. 2.python中的变量只在哪里需要设置内部变量,在__init__函数中. 3.map()会 ...
- 在Proxmox VE上运行OpenWrt/LEDE虚拟机——导入OW/LEDE固件文件到虚拟机中
PVE的OW/LEDE虚拟机初始化创建完成后,需要将编译好的固件文件上传到PVE主机上,然后转换为更适合KVM使用的磁盘映像格式并导入到OW/LEDE虚拟机中,这样就可以更好地使用基于KVM的OW/L ...
- 用简单的JS代码制作计算器
代码+注释一共不到200行,是练习交流的必备良药 主界面如下: 操作示意图: 以下是代码部分 HTML: <div> <table class="window"& ...
- Qt 实现超时锁屏
最近使用Qt实现超时锁屏的功能(工控机触摸屏),当手长时间不触摸屏幕的时候,程序超时会显示锁屏窗口. 一.效果 主窗口超时显示锁屏窗口: 系统窗口超时显示锁屏窗口: 二.实现思路 首先开启一个线程用于 ...
- PyCharm+SVN配置使用教程
一.说明 去年写“PyCharm+Miniconda3安装配置教程”的时候就想把配置SVN的内容加上,但刚开始使用不是很清楚操作就先算了,然后到后边知道怎么操作之后觉得比较简单不写也可以. 一是昨天使 ...
- Qt 文件选项对话框弹出两次
1 问题 在Qt 5.12.0 版本中,用 QFileDialog 类来做文件选择时候,发现当弹出对话框后,选择完文件后,又弹出文件选择对话框. 2 原因查找 2.1 代码 QFileDialog ...