最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
大白话讲解Promise,搞懂jquery中的Promise
时间:2016-03-31 编辑:简简单单 来源:一聚教程网
先讲$.Deferred
jquery用$.Deferred实现了Promise规范,$.Deferred是个什么玩意呢?还是老方法,打印出来看看,先有个直观印象:
JavaScript
<textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="border: 0px; outline: none; display: block; -webkit-appearance: none; padding: 0px 5px; height: 58.5px; resize: none; overflow: auto; margin: 0px; position: absolute; opacity: 0; box-sizing: border-box; border-radius: 0px; box-shadow: none; white-space: pre; word-wrap: normal; color: rgb(0, 0, 0); tab-size: 4; z-index: 0; font-size: 13px !important; line-!important; font-family: Monaco, MonacoRegular, 'Courier New', monospace !important; background-image: initial; background-attachment: initial; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;">
1 2 | var def = $.Deferred(); console.log(def); |
输出如下:
$.Deferred()返回一个对象,我们可以称之为Deferred对象,上面挂着一些熟悉的方法如:done、fail、then等。jquery就是用这个Deferred对象来注册异步操作的回调函数,修改并传递异步操作的状态。
Deferred对象的基本用法如下,为了不与ajax混淆,我们依旧举setTimeout的例子:
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 | function runAsync(){ var def = $.Deferred(); //做一些异步操作 setTimeout(function(){ console.log('执行完成'); def.resolve('随便什么数据'); }, 2000); return def; } runAsync().then(function(data){ console.log(data) }); |
在runAsync函数中,我们首先定义了一个def对象,然后进行一个延时操作,在2秒后调用def.resolve(),最后把def作为函数的返回。调用runAsync的时候将返回def对象,然后我们就可以.then来执行回调函数。
是不是感觉和ES6的Promise很像呢?我们来回忆一下第一篇中ES6的例子:
JavaScript
1 2 3 4 5 6 7 8 9 10 11 | function runAsync(){ var p = new Promise(function(resolve, reject){ //做一些异步操作 setTimeout(function(){ console.log('执行完成'); resolve('随便什么数据'); }, 2000); }); return p; } runAsync() |
区别在何处一看便知。由于jquery的def对象本身就有resolve方法,所以我们在创建def对象的时候并未像ES6这样传入了一个函数参数,是空的。在后面可以直接def.resolve()这样调用。
这样也有一个弊端,因为执行runAsync()可以拿到def对象,而def对象上又有resolve方法,那么岂不是可以在外部就修改def的状态了?比如我把上面的代码修改如下:
JavaScript
1 2 3 4 5 | var d = runAsync(); d.then(function(data){ console.log(data) }); d.resolve('在外部结束'); |
现象会如何呢?并不会在2秒后输出“执行完成”,而是直接输出“在外部结束”。因为我们在异步操作执行完成之前,没等他自己resolve,就在外部给resolve了。这显然是有风险的,比如你定义的一个异步操作并指定好回调函数,有可能被别人给提前结束掉,你的回调函数也就不能执行了。
怎么办?jquery提供了一个promise方法,就在def对象上,他可以返回一个受限的Deferred对象,所谓受限就是没有resolve、reject等方法,无法从外部来改变他的状态,用法如下:
JavaScript
-
下一个: H5单页面手势滑屏切换原理