先前了解了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的用法

jquery的Deferred对象上还有一个always方法,不论执行完成还是执行失败,always都会执行,有点类似ajax中的complete。

$.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>

运行代码

jquery中没有像ES6中的race方法吗?就是以跑的快的为准的那个方法。对的,jquery中没有。
以上就是jquery中Deferred对象的常用方法了。
 
在上一篇和本篇当中,都是用一次性定时器来代替了异步请求进行数据处理。为什么没用ajax呢,不是因为麻烦,在这里要说一下ajax和Deferred的联系:
jquery的ajax返回一个受限的Deferred对象,也就是没有resolve方法和reject方法,不能从外部改变状态,既然是Deferred对象,那么我们上面讲到的所有特性,ajax也都是可以用的。比如链式调用,连续发送多个请求:
<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的更多相关文章

  1. jQuery的Promise

    认识jQuery的Promise   先前了解了ES6的Promise对象,来看看jQuery中的Promise,也就是jQuery的Deferred对象. 打开浏览器的控制台先. <scrip ...

  2. jquery的promise实践--连续加载图片

    在javascript设计模式实践之代理模式--图片预加载中用代理模式实现了图片预加载功能. 现在就更进一步,完成一个能够一张一张的连续图片加载的功能. 功能: 1.一张一张加载图片. 2.加载错误, ...

  3. jquery.Deferred promise解决异步回调

    我们先来看一下编写AJAX编码经常遇到的几个问题: 1.由于AJAX是异步的,所有依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套,ajax等异步操作越多,嵌套层次就会越 ...

  4. 浅谈jQuery的promise

    jquery中的Promise,也就是我们所知道的Deferred对象. 举例1: var data=""; function runAsync(){ var def = $.De ...

  5. Jquery的promise对象

    一直用jquery,ajax一直是这么写: $.ajax({ url: 'abc.com/index', type: 'post', data: { abc:1 }, success: functio ...

  6. jQuery的Promise 这里介绍的很详细

    原文电梯:https://www.cnblogs.com/yelongsan/p/7644239.html 先前了解了ES6的Promise对象,来看看jQuery中的Promise,也就是jQuer ...

  7. jquery ajax promise

    $request = $.getJSON('test.php'); $request.done(process1); $request.done(process2); $request.always( ...

  8. jquery deferred promise

    <script type="text/javascript">/* Deferredstate (then,done, fail, always,pipe, progr ...

  9. 通过 ES6 Promise 和 jQuery Deferred 的异同学习 Promise

    Deferred 和 Promise ES6 和 jQuery 都有 Deffered 和 Promise,但是略有不同.不过它们的作用可以简单的用两句话来描述 Deffered 触发 resolve ...

随机推荐

  1. Cython的用法以及填坑姿势

    因为项目需要,需要优化已有的Python代码.目前Python代码的执行过程是将Python代码转变成一行行指令,然后解释器解释指令的执行,调用到C代码层.如果去掉指令解释这个阶段,直接进入C代码层, ...

  2. Gvim安装nerd_tree插件

    1.先去官网下载nerd_tree插件 http://www.vim.org/scripts/script.php?script_id=1658 2.解压缩将nerd_tree目录下的doc目录和pl ...

  3. Swift4.0 Array详解

    数组的介绍 数组(Array)是一串有序的由相同类型元素构成的集合,数组中的集合元素是有序的,可以重复出现.在Swift中数组类型是Array,是一个泛型集合.数组分成:可变数组和不可变数组,分别使用 ...

  4. Wireshark抓包TCP三次握手数据

    抓包工具 - Wireshark(详细介绍与TCP三次握手数据分析) 功能使用的详细介绍 wireshark(官方下载网站: http://www.wireshark.org/),是用来获取网络数据封 ...

  5. 超级简单实用的前端必备技能-javascript-全屏滚动插件

      fullPage.js fullPage.js是一个基于jQuery的全屏滚动插件,它能够很方便.很轻松的制作出全屏网站 本章内容将详细介绍Android事件的具体处理及常见事件. 主要功能 支持 ...

  6. 【集美大学1411_助教博客】团队作业4——第一次项目冲刺(Alpha版本) 成绩

    写在前面的话 第一次alpha冲刺,大家完成得都很好,从博客中体现出来的是所有团队都完成了预期的目标. 一个团队从最初建立,到磨合,到做出一个能被接受的产品,真是一件不容易的事情.就好像TheNexu ...

  7. 【Beta阶段】第四次scrum meeting

    Coding/OSChina 地址 1. 会议内容 学号 主要负责的方向 昨日任务 昨日任务完成进度 接下去要做 99 PM 查找适合的素材模块,和105一起把手势功能连接到APP上 100% 查阅换 ...

  8. sudoku--设想

    在查阅了一些资料和自己动手写一写后,找到一种可行的解法. 第一步 首先将9x9的数独方格分成九份3x3的九宫格,如下图 B1 B2 B3 B4 B5 B6 B7 B8 B9 而后在左上角的B1上随机生 ...

  9. 201521123068《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 点击->面向对象学习 2. 书面作业 1.clone ...

  10. 201521123113 《Java程序设计》第3周学习总结

    1. 本周学习总结 2.书面作业 Q1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; p ...