未加星标

精通 Javascript 中的 Promise

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

ES6原生提供了 Promise 对象。

到底是何方妖怪呢?打出来看看:


精通 Javascript 中的 Promise

所谓 Promise,就是一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。

Promise 对象有以下两个特点。

(1)对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是 Promise 这个名字的由来,它的英语意思就是「承诺」,表示其他手段无法改变。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise 对象提供统一的接口,使得控制异步操作更加容易。

Promise 也有一些缺点。首先,无法取消 Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。第三,当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

废话不多说,直接上demo:


精通 Javascript 中的 Promise
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Promise 学习笔记</title> <script type="text/javascript"> window.onload = function() { function pms1() { return new Promise(function(resolve, reject) { setTimeout(function() { console.log('执行任务1'); resolve('执行任务1成功'); }, 2000); }); } function pms2() { return new Promise(function(resolve, reject) { setTimeout(function() { console.log('执行任务2'); resolve('执行任务2成功'); }, 2000); }); } function pms3() { return new Promise(function(resolve, reject) { setTimeout(function() { console.log('执行任务3'); resolve('执行任务3成功'); }, 2000); }); } pms1().then(function(data) { console.log('第1个回调:' + data); return pms2(); }) .then(function(data) { console.log('第2个回调:' + data); return pms3(); }) .then(function(data) { console.log('第3个回调:' + data); return '还没完!该结束了吧!' }).then(function(data) { console.log(data); }); } </script> </head> <body> </body> </html>
精通 Javascript 中的 Promise
精通 Javascript 中的 Promise

怎么样?是不是灰常简单啊!

demo2:


精通 Javascript 中的 Promise
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> window.onload = function() { function pms1() { return new Promise(function(resolve, reject) { setTimeout(function() { var num = Math.ceil(Math.random() * 10); //生成1-10的随机数 if(num <= 5) { resolve(num); } else { reject('数字太大了吧!'); } }, 2000); }); } setInterval(function() { pms1().then(function(data) { //小于等于5的 console.log(data); }, function(data) { //大于的 console.log(data); }) }, 1000); } </script> </head> <body> </body> </html>
精通 Javascript 中的 Promise
精通 Javascript 中的 Promise

Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 方法和 reject 方法。

如果异步操作成功,则用 resolve 方法将 Promise 对象的状态,从「未完成」变为「成功」(即从 pending 变为 resolved);

如果异步操作失败,则用 reject 方法将 Promise 对象的状态,从「未完成」变为「失败」(即从 pending 变为 rejected)。

all的用法: demo:
精通 Javascript 中的 Promise
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Promise 学习笔记</title> <script type="text/javascript"> window.onload = function() { function pms1() { return new Promise(function(resolve, reject) { setTimeout(function() { console.log('执行任务1'); resolve('执行任务1成功'); }, 2000); }); } function pms2() { return new Promise(function(resolve, reject) { setTimeout(function() { console.log('执行任务2'); resolve('执行任务2成功'); }, 2000); }); } function pms3() { return new Promise(function(resolve, reject) { setTimeout(function() { console.log('执行任务3'); resolve('执行任务3成功'); }, 2000); }); } Promise.all([pms1(), pms2(), pms3()]).then(function(data) { console.log(data); console.log({}.toString.call(data)); }) } </script> </head> <body> </body> </html>
精通 Javascript 中的 Promise
精通 Javascript 中的 Promise

用Promise.all来执行,all接收一个数组参数,里面的值最终都算返回Promise对象。这样,三个异步操作的并行执行的,等到它们都执行完后才会进到then里面。那么,三个异步操作返回的数据哪里去了呢?都在then里面呢,all会把所有异步操作的结果放进一个数组中传给then,就是上面的results。

race的用法all方法的效果实际上是「谁跑的慢,以谁为准执行回调」,那么相对的就有另一个方法「谁跑的快,以谁为准执行回调」,这就是race方法,这个词本来就是赛跑的意思。race的用法与all一样,我们把上面runAsync1的延时改为1秒来看一下:


精通 Javascript 中的 Promise
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Promise 学习笔记</title> <script type="text/javascript"> window.onload = function() { function pms1() { return new Promise(function(resolve, reject) { setTimeout(function() { console.log('执行任务1'); resolve('执行任务1成功'); }, 1000); }); } function pms2() { return new Promise(function(resolve, reject) { setTimeout(function() { console.log('执行任务2'); resolve('执行任务2成功'); }, 2000); }); } function pms3() { return new Promise(function(resolve, reject) { setTimeout(function() { console.log('执行任务3'); resolve('执行任务3成功'); }, 3000); }); } Promise.race([pms1(), pms2(), pms3()]).then(function(data) { console.log(data); //注意上面的延时时间 }) } </script> </head> <body> </body> </html>
精通 Javascript 中的 Promise
精通 Javascript 中的 Promise

看到没:只有第一个执行了回调!

在then里面的回调开始执行时,runAsync2()和runAsync3()并没有停止,仍旧再执行。于是再过1秒后,输出了他们结束的标志。

这个race有什么用呢?使用场景还是很多的,比如我们可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作。

再来看看jquery里面的 $.Deferred:

jquery用$.Deferred实现了Promise规范,$.Deferred是个什么玩意呢?还是老方法,打印出来看看,先有个直观印象:

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

输出如下:


精通 Javascript 中的 Promise

$.Deferred()返回一个对象,我们可以称之为Deferred对象,上面挂着一些熟悉的方法如:done、fail、then等。jquery就是用这个Deferred对象来注册异步操作的回调函数,修改并传递异步操作的状态。

Deferred对象的基本用法如下,为了不与ajax混淆,我们依旧举setTimeout的例子:


精通 Javascript 中的 Promise
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> <script type="text/javascript" src="js/jquery-3.1.1.min.js"></script> <script type="text/javascript"> $(function() { function runAsync() { var def = $.Deferred(); setTimeout(function() { console.log('

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

主题: JavaUT数据
分页:12
转载请注明
本文标题:精通 Javascript 中的 Promise
本站链接:http://www.codesec.net/view/482587.html
分享请点击:


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