jquery promise
认识jQuery的Promise
先前了解了ES6的Promise对象,来看看jQuery中的Promise,也就是jQuery的Deferred对象。
打开浏览器的控制台先。
<script>
var defer = $.Deferred();
console.log(defer);
</script>
运行代码
运行结果:

和ES6的Promise对象长的有点像,jQuery的Deferred对象也有resolve、reject、then方法,还有done、fail、always......方法。jQuery就是用这个Deferred对象来注册异步操作的回调函数,修改并传递异步操作的状态。
玩玩Deferred:

<script>
function runAsync(){
var defer = $.Deferred();
//做一些异步操作
setTimeout(function(){
console.log('执行完成');
defer.resolve('异步请求成功之后返回的数据');
}, 1000);
return defer;
}
runAsync().then(function(data){
console.log(data)
});
</script>

运行代码
运行之后,Deferred对象的实例defer通过resolve方法把参数 “异步请求成功之后返回的数据” 传回到then方法中进行接收,,打印。
和ES6的Promise相似,但是有一点点区别,再看下Promise:

<script>
function runAsync(){
var p = new Promise(function(resolve, reject){ setTimeout(function(){
console.log('执行完成');
resolve('异步请求成功之后返回的数据');
}, 1000);
});
return p;
} runAsync().then(function(data){
console.log(data);
});
</script>

运行代码
我们发现:
1、创建Deferred对象的时候没有传参;而创建Promise对象的时候,传了参数(传了一个匿名函数,函数也有两个参数:resolve、reject);
2、Deferred对象直接调用了resolve方法;而Promise对象则是在内部调用的resolve方法;
说明:Deferred对象本身就有resolve方法,而Promise对象是在构造器中通过执行resolve方法,给Promise对象赋上了执行结果的状态。
这样就有一个弊端:因为Deferred对象自带resolve方法,拿到Deferred对象之后,就可以随时调用resolve方法,其状态可以进行手动干预了

<script>
function runAsync(){
var defer = $.Deferred();
//做一些异步操作
setTimeout(function(){
console.log('执行完成');
defer.resolve('异步请求成功之后返回的数据');
}, 1000);
return defer;
}
var der = runAsync();
der.then(function(data){
console.log(data)
});
der.resolve('在外部结束');
</script>

运行代码
这样的话就直接在外部直接给Deferred设置了状态,打印“在外部结束”,1s后打印“执行完成”,不会打印“异步请求成功之后返回的数据”了。
显然,这不好。我发个异步请求,还没收到数据就让人在外部给我结束了。。。。。。。
当然这个坑jQuery肯定会填的,在Deferred对象上有一个promise方法,是一个受限的Deferred对象

<script>
function runAsync(){
var def = $.Deferred();
//做一些异步操作
setTimeout(function(){
console.log('执行完成');
def.resolve('请求成功之后返回的数据');
}, 2000);
return def.promise(); //就在这里调用
}
</script>

所谓受限的Deferred对象,就是没有resolve和reject方法的Deferred对象。这样就无法在外边改变Deferred对象的状态了。
Deferred对象的then方法和done、fail语法糖
我们知道,在ES6的Promise规范中,then方法接受两个参数,分别是执行完成和执行失败的回调,而jquery中进行了增强,还可以接受第三个参数,就是在pending状态时的回调,如下:
deferred.then( doneFilter [, failFilter ] [, progressFilter ] )
then方法:

<script>
function runAsync(){
var def = $.Deferred();
//做一些异步操作
setTimeout(function(){
var num = Math.ceil(Math.random()*10); //生成1-10的随机数
if(num<=5){
def.resolve(num);
}
else{
def.reject('数字太大了');
}
}, 2000);
return def.promise(); //就在这里调用
} runAsync().then(function(d){
console.log("resolve");
console.log(d);
},function(d){
console.log("reject");
console.log(d);
}) </script>

运行代码
Deferred对象的then方法也是可以进行链式操作的。
done,fail语法糖,分别用来指定执行完成和执行失败的回调,与这段代码是等价的:

<script>
function runAsync(){
var def = $.Deferred();
//做一些异步操作
setTimeout(function(){
var num = Math.ceil(Math.random()*10); //生成1-10的随机数
if(num<=5){
def.resolve(num);
}
else{
def.reject('数字太大了');
}
}, 2000);
return def.promise(); //就在这里调用
} runAsync().done(function(d){
console.log("resolve");
console.log(d);
}).fail(function(d){
console.log("reject");
console.log(d);
}) </script>

运行代码
always的用法
$.when的用法
jquery中,还有一个$.when方法来实现Promise,与ES6中的all方法功能一样,并行执行异步操作,在所有的异步操作执行完后才执行回调函数。不过$.when并没有定义在$.Deferred中,看名字就知道,$.when,它是一个单独的方法。与ES6的all的参数稍有区别,它接受的并不是数组,而是多个Deferred对象,如下:

<script>
function runAsync(){
var def = $.Deferred();
//做一些异步操作
setTimeout(function(){
var num = Math.ceil(Math.random()*10); //生成1-10的随机数
def.resolve(num);
}, 2000);
return def.promise(); //就在这里调用
}
$.when(runAsync(), runAsync(), runAsync()) .then(function(data1, data2, data3){
console.log('全部执行完成');
console.log(data1, data2, data3);
});
</script>

运行代码

<script>
req1 = function(){
return $.ajax(/* **** */);
}
req2 = function(){
return $.ajax(/* **** */);
}
req3 = function(){
return $.ajax(/* **** */);
}
req1().then(req2).then(req3).done(function(){ console.log('请求发送完毕'); });
</script>

success、error与complete
这三个方法是我们常用的ajax语法糖。
$.ajax(/*...*/)
.success(function(){/*...*/})
.error(function(){/*...*/})
.complete(function(){/*...*/})
有时候比较喜欢在内部作为属性来处理。
分别表示ajax请求成功、失败、结束的回调。这三个方法与Deferred又是什么关系呢?其实就是语法糖,success对应done,error对应fail,complete对应always,就这样,只是为了与ajax的参数名字上保持一致而已。
总结:
$.Deferred实现了Promise规范,then、done、fail、always是Deferred对象的方法。$.when是一个全局的方法,用来并行运行多个异步任务,与ES6的all是一个功能。ajax返回一个受限的Deferred对象,success、error、complete是ajax提供的语法糖,功能与Deferred对象的done、fail、always一致。
jquery promise的更多相关文章
- jquery promise (Deferred)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 使用Jquery promise 动态引入js文件
动态加载一个js得方式很多,如下方式: /** *一般方式加载 */ function normalLoadScript(url) { var node = document.createElemen ...
- jquery Promise和ES6 Promise的区别
1. Deferred对象有resolve和reject方法,可以直接修改状态 jquery用Deferred实现了Promise规范,Deferred与ES6 Promise的最大区别是: Defe ...
- 通过 ES6 Promise 和 jQuery Deferred 的异同学习 Promise
Deferred 和 Promise ES6 和 jQuery 都有 Deffered 和 Promise,但是略有不同.不过它们的作用可以简单的用两句话来描述 Deffered 触发 resolve ...
- 深入理解 JavaScript 异步系列(2)—— jquery的解决方案
第一部分,jQuery-1.5 之后的 ajax 本地址http://www.cnblogs.com/wangfupeng1988/p/6515779.html未经允许不得转载~ $.ajax这个函数 ...
- jquery源码 DOM加载
jQuery版本:2.0.3 DOM加载有关的扩展 isReady:DOM是否加载完(内部使用) readyWait:等待多少文件的计数器(内部使用) holdReady():推迟DOM触发 read ...
- 原生JS替代jQuery的各种方法汇总
前端发展很快,现代浏览器原生 API 已经足够好用.我们并不需要为了操作 DOM.Event 等再学习一下 jQuery 的 API.同时由于 React.Angular.Vue 等框架的流行,直接操 ...
- jQuery与原生JS相互转化
前端发展很快,现代浏览器原生 API 已经足够好用.我们并不需要为了操作 DOM.Event 等再学习一下 jQuery 的 API.同时由于 React.Angular.Vue 等框架的流行,直接操 ...
- 【jQuery源码】DOM Ready
一直以来,各种JS最佳实践都会告诉我们,将JS放在HTML的最后,即</body>之前,理由就是:JS会阻塞下载,而且,在JS中很有可能有对DOM的操作,放在HTML的最后,可以尽可能的保 ...
随机推荐
- [svc][op]ssh交互yes问题解决-expect
Expect是Unix系统中用来进行自动化控制和测试的软件工具C67默认未安装:使用需要安装: yum install expect -ywhich expect #查看安装路径 核心命令: [roo ...
- 关于haproxy负载均衡的算法整理
目前haproxy支持的负载均衡算法有如下8种: 1:roudrobin 表示简单的轮询,每个服务器根据权重轮流使用,在服务器的处理时间平均分配的情况下这是最流畅和公平的算法.该算法是动态的,对于实例 ...
- 关于 \t 水平制表符 Horizontal Tab (TAB)
今天在学learn python the hard way ex26修改的时候,有一个关于\t的问题,下面分别为代码以及输出结果: 1 poem = """ 2 \tTh ...
- IDEA用maven打war包
打包其实很简单: 把tomcat停掉,点击Maven Projects ,点击clean , 点击package 自动打包完成. 查看包位置: 这是包的位置,通过查看PATH就可以知道你的包在哪里了. ...
- springmvc集成Freemarke配置的几点
项目结构图 废话不多说, 集成步骤: 1.web.xml spring-mvc配置 <?xml version="1.0" encoding="UTF-8&quo ...
- python traceback捕获并打印异常
异常处理是日常操作了,但是有时候不能只能打印我们处理的结果,还需要将我们的异常打印出来,这样更直观的显示错误 下面来介绍traceback模块来进行处理 try: 1/0 except Excepti ...
- python2.7执行shell命令
python学习——python中执行shell命令 2013-10-21 17:44:33 标签:python shell命令 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者 ...
- CentOS清除用户登录记录和命令历史方法
清除登陆系统成功的记录 [root@localhost root]# echo > /var/log/wtmp //此文件默认打开时乱码,可查到ip等信息 [root@localhost roo ...
- 基于jquery带时间轴的图片轮播切换代码
基于jquery图片标题随小圆点放大切换.这是是一款带时间轴的图片轮播切换代码.效果图如下: 在线预览 源码下载 实现的代码. html代码: <div id="decoroll2 ...
- Eclipse下把jar包放到工程lib下和通过buildpath加载有什么不同(解决找不到类的中级方法)
我通过Eclipse的 User Libranry 将jar导入 Eclipse里面,编译没有问题,运行的时候就报class文件没有定义,后来上网上查了下,原因找到啦,是这样的: 用Java Buil ...