Promise对象
1.Promise的含义
Promise是一种异步编程的解决方案,最早由社区提出和实现,ES6正式纳入标准原生提供Promise对象,比传统的 回调函数(会层层嵌套)和事件更为合理、强大,可以将异步操作以同步操作的流程表达出来。
通俗地将:Promise是一个保存着某个未来才会结束的事件(通常是一个异步操作)的结果;
从语法角度:Promise是一个对象,从它可以获取异步操作的消息;提供统一的API,各种异步操作都可以用相同的方法处理。
Promise对象的两个特点:
(1)对象的状态不受外界影响。Promise对象(代表某一个异步操作),有3个状态:pending(进行中),fulfilled(已成功),rejected(已失败)。只有异步操作的异步操作的结果,可以决定可以决定Promise对象当前是哪种状态
(2)一旦状态改变,就不会再变,会一直保持这个结果,这时就称为resolved(已定型)。状态改变只有两种情况:pending-->fulfilled,pending-->rejected,
Promise对象的缺点:
(1)无法取消Promise,一旦新建它就会立即执行,无法中途取消;
(2)如果不设置回调函数,Promise内部抛出错误,不会反应到外部;
(3)当处于pending状态时,无法判断进行到了哪个阶段(刚刚开始还是即将完成)。
如果某些事件不断地反复发生,一般来说,使用 Stream 模式是比部署Promise更好的选择???
2.基本用法
ES6规定,Promise对象是一个构造函数,用来生成一个Promise实例。
生成Promise实例 Promise实例的then方法 例子,setTimeout()的第三个参数以及之后的参数都是传给执行函数(resolve)的 新建Promise实例后就会立即执行的例子注意点:
一个异步操作A的结果是返回另一个异步操作B时:
B的状态会决定A的状态
一个异步操作的结果是另一个异步操作时的情况3.Promise.prototype.then()
因为Promise.prototype.then(),所以Promise实例是有then()方法的
作用:为 Promise 实例添加状态改变时的回调函数。then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数
then方法返回的是一个新的Promise实例(注意,不是原来的那个Promise实例)。
then方法返回一个新的Promise实例因此,可以采用链式写法,即then方法后面再调用另一个then方法
then中的回调函数返回的还是一个Promise对象(例子类似一个Ajax请求成功后再一个Ajax请求)4.Promise.prototype.catch()
then.(null,rejection)的别名,用于指定发生错误时的回调函数
catch()方法例子1 不同的写法 例2Promise异步操作抛出错误或者then回调函数中抛出错误,都能被catch捕获;可以从例1中的等价情况看出
如果Promise状态已经变成resolved,再抛出错误是无效的(抛出错误理论上是要改变状态的);
注意,这并不是说状态变化后resolve()或reject()方法后的代码不再被执行!!!
状态改变后再抛出错误不能被catch到 resolve/reject后的代码还是可以正常执行注意:提倡使用catch,而不是在then中定义Reject状态的回调函数
尽量使用catch而不是then的第二个参数 如果Promise内部出错误,并不会导致外部代码因此而不被执行脚本在服务端执行的情况,此处略,看原文
5.Promise.all()
作用:将多个Promise实例包装成一个Promise对象
const p=Promise.all(具有iterator接口,且返回的每个成员都是Promise实例,如果不是,会通过Promise.resolve()方法转成实例);
结果p的状态规则:
实例(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
注意:如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法;没定义时才会触发Promise.all()的catch方法
6.Promise.race()
作用:和Promise.all()一样,也是将多个Promise实例合并成一个新的实例;
区别是两个方法的p的状态规则不同,
例子,请求超时的处理race的规则是:只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数
7.Promise.resolve()
作用:将现有对象转成Promise对象
例1Promise.resolve()方法的参数有如下4中情况:
(1)参数是一个Promise实例:直接返回该实例
(2)参数是一个thenable对象:
thenable对象指的是具有then方法的对象
thenable对象的处理(3)参数不是有then方法的对象,或者根本不是对象:
即参数是原始值(Undefined,Null,Boolean,Number,String,Symbol),或者是没有then方法的对象,则返回一个新的Promise对象,状态为resolved
(4)不带任何参数:直接返回一个状态为resolved的Promise对象
注意理解:
立即resolve的 Promise 对象,是在本轮“事件循环”(event loop)的结束时,而不是在下一轮“事件循环”的开始时
8.Promise.reject()
作用:返回一个新的Promise实例,状态是rejected
Promise.reject()方法的参数问题9.两个有用的附加方法
(1)done()
Promise 对象的回调链,不管以then方法或catch方法结尾,要是最后一个方法抛出错误,都有可能无法捕捉到(因为 Promise 内部的错误不会冒泡到全局);done方法,总是处于回调链的尾端,保证抛出任何可能出现的错误。
done()中catch错误并抛出作为全局错误(2)finally()
示例:finally()的写法finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。它与done方法的最大区别,它接受一个普通的回调函数作为参数,该函数不管怎样都必须执行。
10.应用
(1)加载图片
(2)Generator函数和Promise结合
generator???11.Promise.try()
解决:不知道或者不想区分,函数f是同步函数还是异步操作,但是想用 Promise 来处理它的问题--同步的写法,同步的依然同步执行,异步的就异步执行;模拟try代码块
目前是提案,但有些库已经实现该功能
网友评论