1. 概念

  Promise对象用于异步(asynchronouss)计算,一个Promise对象代表着一个还未完成,但预期完成的操作。

2. 出现原因:

 1)  如果你需要通过ajax发送多次请求,而每一次请求依赖上一次请求返回的结果作为参数来继续下次的请求,这样的话,就需要这么写代码:

  

  上面的例子,假设请求C需要依赖B返回的数据,那么C需要放在B的success函数里面。同样的,A需要依赖B返回的数据,那么A也需要放在B的success函数里面。假设现在存在很多个请求,请求之前是相互的依赖关系,那么我们需要嵌套很多层,这样的话,代码的可读性就很差,不直观,调试起来也不方便,维护也不方便。

 2)  如果请求C需要依赖A和B的结果,而A,B是互相独立的,没有依赖关系,那么如果使用上面的实现方法,就使得A(B)需要依赖B(A)完成之后才能调用,这样需要更长的等待时间。

  所以,为了处理这种回调函数层层嵌套的问题(又称“回调地狱”),所以Promise就出现了。

3. 语法

  new Promise(function(resolve,reject){

  //操作…

  });

  Promise对象是全局对象,你也可以理解为一个类,创建Promise实例的时候,利用new关键字。其中,resolve和reject两个参数是函数对象。resolve是用于处理执行成功的场景,reject是用在处理执行失败的场景,一旦操作完成就可以调用这两个函数。具体的调用是通过then()方法来绑定操作后的处理程序,具体使用见之后的讲解。

4. 解析

Promise对象的三种状态:

 1)  pending:刚刚创建一个Promise实例的时候,表示初始化状态

 2)  fulfilled:resolve方法调用的时候,表示操作成功

 3)  rejected:reject方法调用的时候,表示操作失败

  pending状态的promise对象既可转换为带着一个成功值的fulfilled 状态,也可变为带着一个失败信息的 rejected 状态。当状态发生转换时,promise.then绑定的方法(函数句柄)就会被调用。(当绑定方法时,如果 promise对象已经处于 fulfilled 或 rejected 状态,那么相应的方法将会被立刻调用, 所以在异步操作的完成情况和它的绑定方法之间不存在竞争条件。)

  

(图片来源:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise)

5. 属性

  Promise.length:长度属性,其值为1(构造参数的数目)

  Promise。prototype:Promise构造器的原型

6. 方法

 1)  Promise.then()方法:用于绑定处理操作后的处理程序。

  

 2)  Promise.catch()方法:用于处理操作异常后的页面。

  

 3)  then()和catch()综合使用的例子:

  

 4)  层层依赖用Promise处理:

   代码:

 let pro = new Promise(function(resolve,reject){
if(true){
resolve('操作成功');//此时resolve函数会返回值
}
else{
reject('操作失败');
}
}); pro.then(requestA)
.then(requestB)
.then(requestC)
.catch(requestError); function requestA(res){
console.log(res);//输出resolve返回的值-->操作成功
console.log("请求A成功");
return "请求A,下一步就是B你了";
} function requestB(res){
console.log("上一步是"+res);
console.log("请求B成功");
return "请求B,下一步是C你了";
} function requestC(res){
console.log("上一步是"+res);
console.log("请求C成功");
} function requestError(){
console.log("请求失败");
}

  

  结果:

  

  解析:上面的例子中:先创建一个实例,还声明了4个函数,其中三个是分别代表着请求A、B、C的;有了then方法,按照调用顺序,很直观的完成了三个操作的绑定。并且,如果请求B依赖请求A的结果,那么,可以在请求A的程序用return语句把需要的数据作为参数,传递给下一个请求。

  (图片例子来源微信公众号:“web前端教程”)

 5)  Promise.all()方法:接受一个数组作为参数,数组的元素是Promise实例对象,当参数中的实例对象的状态都为fulfilled时,Promise.all()才会有返回。

  

  解析:pro2先进入成功fulfilled状态,才是Promise.all()还不能进入then方法,等到5s之后,pro1进入成功fulfilled状态,Promise.all()才进入then方法,才输出结果:["实例1操作成功", "实例2操作成功"]

 6)  Promise.race():接受一个数组作为参数,数组的元素是Promise实例对象,当参数中的实例对象有一个状态(无论是fulfilled还是rejected)发生变化的时候,Promise.race()就会进入then方法。

  

7. 原型

 属性:

  Promise.prototype.constructor:返回创建了实例原型的函数.  默认为 Promise 函数

 方法:

  Promise.prototype.catch(onRejected):添加一个否定(rejection) 回调到当前 promise, 返回一个新的promise。如果这个回调被调用,新 promise 将以它的返回值来resolve,否则如果当前promise 进入fulfilled状态,则以当前promise的肯定结果作为新promise的肯定结果.

  Promise.prototype.then(onFulfilled, onRejected):添加肯定和否定回调到当前 promise, 返回一个新的 promise, 将以回调的返回值 来resolve.

8. 例子

 参考的例子:

 <div id="log"></div>
<script>
'use strict';
var promiseCount = 0;
function testPromise() {
var thisPromiseCount = ++promiseCount;
var log = document.getElementById('log');
log.insertAdjacentHTML('beforeend', thisPromiseCount + ') 开始(同步代码开始)<br/>');
// 我们创建一个新的promise: 然后用'result'字符串完成这个promise (3秒后)
var p1 = new Promise(function (resolve, reject) {
// 完成函数带着完成(resolve)或拒绝(reject)promise的能力被执行
log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Promise开始(异步代码开始)<br/>'); // 这只是个创建异步完成的示例
window.setTimeout(function () {
// 我们满足(fullfil)了这个promise!
resolve(thisPromiseCount)
}, Math.random() * 2000 + 1000);
});
// 定义当promise被满足时应做什么
p1.then(function (val) {
// 输出一段信息和一个值
log.insertAdjacentHTML('beforeend', val + ') Promise被满足了(异步代码结束)<br/>');
}); log.insertAdjacentHTML('beforeend', thisPromiseCount + ') 建立了Promise(同步代码结束)<br/><br/>');
}
testPromise();
testPromise();
testPromise();

 结果:

  

 另一个比较好的例子:

  https://github.com/mdn/promises-test/blob/gh-pages/index.html

9. 总结

 Promise是一个让开发者更合理、更规范地用于处理异步操作的对象。

10. 参考资料

  https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise

  https://developer.mozilla.org/zh-CN/docs/Web/API/Element/insertAdjacentHTML

11. 接下来的安排

  ajax源码运用

  结合promise与ajax源码运用

ECMAScript6的Promise对象的更多相关文章

  1. 关于promise对象的笔记

    1.promise对象是ECMAScript6的新特性,很多新的JS框架都有它的实现和应用 2.promise常用于异步调用(ajax)中 3.promise主要用于解决回调函数层层嵌套的写法 4.要 ...

  2. angular学习笔记(二十八-附2)-$http,$resource中的promise对象

    下面这种promise的用法,我从第一篇$http笔记到$resource笔记中,一直都有用到: HttpREST.factory('cardResource',function($resource) ...

  3. ES6深入学习记录(二)promise对象相关

    1.Promise的含义 Promise是异步编程的一种解决方案,比传统的解决方案--回调函数和事件更合理和强大.ES6将其写进了语言标准,统一了用法,原生提供了promise对象. 所谓Promis ...

  4. es6中的promise对象

    Promise是异步里面的一种解决方案,解决了回调嵌套的问题,es6将其进行了语言标准,同意了用法,提供了`promise`对象, promise对象有三种状态:pending(进行中) .Resol ...

  5. ES6的promise对象应该这样用

    ES6修补了一位Js修真者诸多的遗憾. 曾几何时,我这个小白从js非阻塞特性的坑中爬出来,当我经历了一些回调丑陋的写法和优化的尝试之后,我深深觉得js对于多线程阻塞式的开发语言而言,可能有着其太明显的 ...

  6. Angularjs promise对象解析

    1.先来看一段Demo,看完这个demo你可以思考下如果使用$.ajax如何处理同样的逻辑,使用ng的promise有何优势? var ngApp=angular.module('ngApp',[]) ...

  7. JavaScript异步编程(1)- ECMAScript 6的Promise对象

    JavaScript的Callback机制深入人心.而ECMAScript的世界同样充斥的各种异步操作(异步IO.setTimeout等).异步和Callback的搭载很容易就衍生"回调金字 ...

  8. Promise对象

    1.Promise思想:每一个异步任务立刻返回一个Promise对象,由于是立刻返回,所以可以采用同步操作的流程.这个Promises对象有一个then方法,允许指定回调函数,在异步任务完成后调用. ...

  9. angularJS中的Promise对象($q)的深入理解

    原文链接:a better way to learn AngularJS - promises AngularJS通过内置的$q服务提供Promise编程模式.通过将异步函数注册到promise对象, ...

随机推荐

  1. python第二天-linux权限管理

    (1)linux登陆密码忘了,怎么办? 把系统重启,在进入系统之前不断的按键盘左上角的"Esc"键会进入这样一个画面,按键盘上的e进入编辑. 进入这个画面以后,通过键盘的上下方向键 ...

  2. java 基本语法

    标识符 标识符就是给变量.类或方法起的名字. 标识符由26个英文字符大小写(a~zA~Z).数字(0~9).下划线(_)和美元符号($)组成 不能以数字开头,不能是关键字 严格区分大小写 标识符的可以 ...

  3. String类字符串截取示范

    package it.com; // 要求:對字符串“jflksjdfnbalkdfjnbaddddnbahhuhnbauuuuahnbahdfunbadhfudf”进行检索:判断有多少个nba; / ...

  4. TCP、UDP、IP 协议分析(转)

    http://blog.chinaunix.net/uid-26833883-id-3627644.html

  5. java 的面向对象

    1.java是什么语言: java也属于面向对象编程语言. 2.面向对象的三大特性: 封装 ,继承, 多态. 3.什么是对象: 对象是真实存在的唯一失误. 面向对象的英文是(oop),面向对象的编程思 ...

  6. ELK日志管理之——logstash配置语法

    Logstash 设计了自己的 DSL -- 有点像 Puppet 的 DSL,或许因为都是用 Ruby 语言写的吧 -- 包括有区域,注释,数据类型(布尔值,字符串,数值,数组,哈希),条件判断,字 ...

  7. 【译】RabbitMQ:发布-订阅(Publish/Subscribe)

    在前一篇教程中,我们创建了一个工作队列,我们假设在工作队列后的每一个任务都只被调度给一个消费者.在这一部分,我们将做一些完全不一样的事情,调度同一条消息给多个消费者,也就是有名的“发布-订阅”模式.为 ...

  8. Haproxy+Keepalived高可用负载均衡详细配置

    本文所使用的环境: 10.6.2.128    centos6.5 10.6.2.129    centos6.5 VIP  为10.6.2.150 要实现的目标: 实现10.6.2.128和10.6 ...

  9. IP地址子网掩码主机地址网络号主机号

    (1)子网掩码1所对应的位为网络号位 而所对应的位为主机号位 IP地址+子网掩码=网络号: IP地址+子网掩码(反码)=主机号. (2)主机号中的m位被用来表示网络号了,也就是子网号,将0-255划分 ...

  10. zookeeper学习(一)安装、配置、运行

    说明:zookeeper完全可以standalone,也可以伪集群形式,当然生产中都是集群形式.另外,也可以在windows下运行. 如果只是研究用,完全可以在windows下使用standalone ...