未加星标

对程序员的一个Promise(二)

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二03 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏

在上一篇文章 《对程序员的一个Promise(一)》 中,分享了一下了ES6中Promise的用法,但是需要浏览器支持Promise。在jQuery中也有Promise,就让我来看看jQuery中的Promise是怎么用的。

jQuery中的Promise

在jQuery中,首先要通过Deferred方法获取到Deferred对象,让我们来打印出来看看它有什么方法。

var d = $.Deferred(); console.log(d);

最后输出如下:


对程序员的一个Promise(二)

我们可以看到$.Deferred()返回是一个对象(Deferred对象),也有resolve、then、reject等一些我们熟悉的方法,让我们来看看它是怎么用的。

基本用法 functiongetPromise1(){ var d = $.Deferred(); setTimeout(()=> { console.log('异步1结束'); d.resolve('异步1数据'); }, 200); return d; } var def = getPromise1(); def.then((data) => { console.log(data); });

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

感觉跟ES6中Promise的用法很相似。我们首先通过$.Deferred()获取到了Deferred对象,然后在异步成功后返回数据,然后在then方法中对异步数据进行处理。

但是跟ES6中不一样的是,异步没有放到Promise的构造函数中,在异步成功后,调用了Deferred对象的resolve方法。then方法处理回调数据还是一样的。

发现问题

既然Deferred对象上有resolve()方法,那么是不是在外部就能够调用resolve()方法就能够修改Promise的状态呢。把上面的代码进行如下改写:

functiongetPromise1(){ var d = $.Deferred(); setTimeout(()=> { console.log('异步1结束'); d.resolve('异步1数据'); }, 300); return d; } var def = getPromise1(); def.then((data) => { console.log(data); }); def.resolve('外部数据1');

输出结果如下:


对程序员的一个Promise(二)

可以看到我们在函数的外面调用了resolve()方法提前让异步结束并且返回了数据。这样Promise的状态就能够被随意的改变,肯定是不行的。

解决问题

将代码进行如下改进,在返回的对象上多加一个promise()方法:

functiongetPromise1(){ var d = $.Deferred(); setTimeout(()=> { console.log('异步1结束'); d.resolve('异步1数据'); }, 300); return d.promise(); } var def = getPromise1(); def.then((data) => { console.log(data); }); def.resolve('外部数据1');

输出结果如下:


对程序员的一个Promise(二)

这时候,如果在函数的外部调用resolve()方法会报错,告诉我们resolve()方法不存在,异步也会“如期”执行完成。如果我们将def对象打印出来看的话会发现并没有resolve()方法。

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

成功和失败的回调

和ES6中的Promise相似,then也支持接收两个参数,分别是执行成功的回调和执行失败的回调。

functiongetPromise1(){ var d = $.Deferred(); setTimeout(()=> { var number = Math.round(Math.random()*10); if(number %2 == 0) { d.resolve('成功数据'); } else { d.reject('失败数据'); } }, 300); return d.promise(); } var def = getPromise1(); def.then( (data) => { console.log('成功回调'); console.log(data); }, (data) => { console.log('失败回调'); console.log(data); } )

除此之外,jQuery还新增了两个函数,done()和fail()分别用来指定成功的回调和失败的回调。因此,上面的代码和下面的代码是等价的:

var def = getPromise1(); def.done((data) => { console.log('成功回调'); console.log(data); }); def.fail((data) => { console.log('失败回调'); console.log(data); }); 链式调用

既然是Promise,那么then()肯定也支持链式调用的,这边也不在赘述,跟ES6中是一样的用法,不太熟悉的可以戳这边 《对程序员的一个Promise(一)》

扩展函数

jQuery中没有all和race方法,但是扩展了一些其他的方法。

always方法

always方法就是不管执行成功或者失败,都会执行的,有点类似ajax的complete方法。

var def = getPromise1(); def.done((data) => { console.log('成功回调'); console.log(data); }); def.fail((data) => { console.log('失败回调'); console.log(data); }); def.always(()=> { console.log('总是执行') })

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

when方法

when方法和ES6中的all方法功能一样,都是并行执行异步,所有异步执行完成后才执行回调函数。不过when方法是挂载在全局中的方法,而且,它接受的参数也是多个对象。

functiongetPromise1(){ var d = $.Deferred(); setTimeout(()=> { d.resolve('成功数据1'); }, 100); return d.promise(); } functiongetPromise2(){ var d = $.Deferred(); setTimeout(()=> { d.resolve('成功数据2'); }, 200); return d.promise(); } functiongetPromise3(){ var d = $.Deferred(); setTimeout(()=> { d.resolve('成功数据3'); }, 300); return d.promise(); } $.when(getPromise1(), getPromise2(), getPromise3()) .then((data1,data2,data3) => { console.log('执行完成'); console.log(data1, data2, data3); }) 理解ajax的本质

平时我们都是这么请求ajax异步的:

$.ajax({ url:'test.json', success:function(data){ // ... }, error:function(data){ // ... } });

上面的代码,平时的工作中我们肯定也写了无数遍了,已经很熟悉了,但是这个ajax()方法返回的是什么呢,让我们打印出来看下:


对程序员的一个Promise(二)

难道是巧合么?我们看到了熟悉的always()、done()、fail()、promise()、then()等方法。没错,ajax返回的也是一个Deferred对象,既然是Deferred对象,那么肯定也支持链式调用了。

那么将ajax方法进行如下改写:

functiongetAjax1(){ var def = $.ajax({url:'test.json'}); return def.promise(); } var def1 = getAjax1(); def1.then((data) => { console.log(data); });

既然是Deferred对象,那么done()、fail()、$.when()这些方法也能使用,这里就不再赘述了。

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

主题: 程序员jQuery数据Ajax浏览器博客
分页:12
转载请注明
本文标题:对程序员的一个Promise(二)
本站链接:http://www.codesec.net/view/531330.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(26)