1.前言

  在平时的业务开发中,前端通常需要请求后台获取数据,或者NodeJs读取文件等等一系列的异步操作,我们通常需要利用异步操作的结果或者对异步操作的结果进行处理。通常我们的解决方案是:在异步操作成功或者失败的回调函数里面写方法,在异步操作比较简单的时候这样写代码还是比较好理解的,当业务逐渐趋于复杂,这就形成了回调地狱,代码嵌套层数太多并且难以理解。不过,办法总是有的,可以使用ES6的新特性Promise来解决问题。

2.Promise的定义

  Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

Promise对象有以下两个特点。

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

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

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

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

3.基本用法

  ES6规定,Promise对象是一个构造函数,用来生成Promise实例

代码如下:

  1. const promise=new Promise(function(resolve,reject){
  2. if(/* 异步操作成功*/){
  3. resolve(value)
  4. }else{
  5. reject(error);
  6. }
  7. });

Promise构造函数接受一个函数作为参数,改函数的两个参数分别是resolve与reject,resolve函数的作用是:将Promsie对象的状态从“未完成”变为“成功”,在异步操作成功时回调,并将异步操作的结果value作为参数传递出去;reject函数的作用是:Promise对象的状态由“未完成”变为“失败”,在异步操作失败时调用,并将异步操作报出的错误作为参数传递出去。

Promise实例生成以后,可以用then方法分别制定resolved的状态和reject状态的回调函数。

代码如下:

  1. promise.then(function(value) {
  2. // success
  3. }, function(error) {
  4. // failure
  5. });

4.小例子-封装Ajax操作

  1. const getJSON = function(url) {
  2. const promise = new Promise(function(resolve, reject){
  3. const handler = function() {
  4. if (this.readyState !== 4) {
  5. return;
  6. }
  7. if (this.status === 200) {
  8. resolve(this.response);
  9. } else {
  10. reject(new Error(this.statusText));
  11. }
  12. };
  13. const client = new XMLHttpRequest();
  14. client.open("GET", url);
  15. client.onreadystatechange = handler;
  16. client.responseType = "json";
  17. client.setRequestHeader("Accept", "application/json");
  18. client.send();
  19.  
  20. });
  21.  
  22. return promise;
  23. };
  24.  
  25. getJSON("./js/package.json").then(function(json) {
  26. console.log('Contents: ' , json);
  27. }, function(error) {
  28. console.error('出错了', error);
  29. });

以上的代码是通过用原生的Ajax和Promise实现的获取json的一个方法,在网页中运行得出以下的结果:

5.reject状态回调方法的写法

  1. promise
  2. .then(function(data) {
  3. // success
  4. }, function(err) {
  5. // error
  6. });

以上是我们的reject状态方法,可以作为promsie对象then方法的第二个参数。不过这样写有个缺点是:如果在resolve状态之后再抛出错误,则不会捕获。

推荐写法:

  1. // 推荐写法
  2. promise
  3. .then(function(data) { //cb
  4. // success
  5. })
  6. .catch(function(err) {
  7. // error
  8. });

  通过Promise这种写法,我们使很多异步操作的方法写法同步化,能够更好的组织优化代码,而且在捕获错误也更加容易,方便我们调试解决问题。不足之处,多多指正。


参考资料:

《ECMAScript 6 入门》-阮一峰

《MDN-Promise》

ES6之Promise学习与实践的更多相关文章

  1. ES6语法的学习与实践

    ES6是JavaScript语言的新一代标准,是ECMAScript的第六个版本,加入了很多新的功能和语法,在很多框架,如在使用Vue,React等框架的项目中一般都采用ES6语法来编写的,下面对经常 ...

  2. es6从零学习(二):promise

    es6从零学习(二):promise 一:promise的由来 某些情况下,回调嵌套很多时,代码就会非常繁琐,会给我们的编程带来很多的麻烦,这种情况俗称——回调地狱.由此,Promise的概念就由社区 ...

  3. Weex学习与实践

    Weex学习与实践(一):Weex,你需要知道的事 本文主要介绍包括Weex基本介绍.Weex源码结构.初始化工程.we代码结构.Weex的生命周期.Weex的工作原理.页面间通信.boxmodel ...

  4. Promise 学习笔记 - 时间支配者

    本文同步自我的个人博客:http://www.52cik.com/2015/11/08/promise.html JavaScript 的 promises 事实标准称为 Promises/A+.ES ...

  5. ES6的promise对象研究

    ES6的promise对象研究 什么叫promise? Promise对象可以理解为一次执行的异步操作,使用promise对象之后可以使用一种链式调用的方式来组织代码:让代码更加的直观. 那我们为什么 ...

  6. ES6之Promise用法详解

    一 前言 本文主要对ES6的Promise进行一些入门级的介绍.要想学习一个知识点,肯定是从三个方面出发,what.why.how.下面就跟着我一步步学习吧~ 二 什么是Promise 首先是what ...

  7. 关于ES6的Promise的使用深入理解

    ES6的promise对象研究 什么叫promise? Promise对象可以理解为一次执行的异步操作,使用promise对象之后可以使用一种链式调用的方式来组织代码:让代码更加的直观. 那我们为什么 ...

  8. 【ES5 ES6】使用学习

    [ES5 ES6]使用学习 转载: ============================================================= 1.Promise 2.下划线转驼峰,驼 ...

  9. 教你如何使用ES6的Promise对象

    教你如何使用ES6的Promise对象 Promise对象,ES6新增的一个全新特性,这个是 ES6中非常重要的一个对象 Promise的设计初衷 首先,我们先一起了解一下,为什么要设计出这么一个玩意 ...

随机推荐

  1. php获取汉字首字母实例

    在我们实际开发工作中,有时候需要获取输入汉字的首字母,然后存到库中,方便用户搜索相关信息,下面给出php代码,留做备用: //新添加获取汉子首字,首字字母 function pinyin($zh){ ...

  2. MySQL数据库主从分离的配置方法

    1.介绍 MySQL数据库设置读写分离,可以使对数据库的写操作和读操作在不同服务器上执行,提高并发量和响应速度.现在的网站一般大点的,都采用有数据库主从分离.读写分离,既起到备份作用也可以减轻数据库的 ...

  3. HTML5总结

    HTML的定义 HyperText Markup Language 超文本标记语言 超级文本标记语言是标准通用标记语言下的一个应用,也是一种规范,一种标准, 它通过标记符号来标记要显示的网页中的各个部 ...

  4. 登录测试用例sql语句注入

    利用SQL注入漏洞登录后台的实现方法 作者: 字体:[增加 减小] 类型:转载 时间:2012-01-12我要评论 工作需要,得好好补习下关于WEB安全方面的相关知识,故撰此文,权当总结,别无它意.读 ...

  5. CAS与OAuth2的区别

    CAS与OAuth2的区别 一. CAS的单点登录时保障客户端的用户资源的安全 . OAuth2则是保障服务端的用户资源的安全 . 二. CAS客户端要获取的最终信息是,这个用户到底有没有权限访问我( ...

  6. PAT1083:List Grades

    1083. List Grades (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Given a l ...

  7. Java 8 Optional类深度解析(转)

    经常会遇到这样的问题,调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法.我们首先要判断这个返回值是否为null,只有在非空的前提下才能将其作为其他方法的参数. 新版本的Java,比如J ...

  8. 网络编程之套接字(udp)

    Socket的英文原义是“孔”或“插座”.作为BSD UNIX的进程通信机制,取后一种意思.通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机 ...

  9. python字符串操作实方法大合集

    python字符串操作实方法大合集,包括了几乎所有常用的python字符串操作,如字符串的替换.删除.截取.复制.连接.比较.查找.分割等,需要的朋友可以参考下:   #1.去空格及特殊符号 s.st ...

  10. Embedded servlet containers

    73. Embedded servlet containers 73.1 Add a Servlet, Filter or Listener to an application There are t ...