Promise对象的含义和基本用法
1.Promise是异步编程的一种解决方案,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。
2.Promise有以下两个特点:
(1) 对象状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。
(2) 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能,从pending变成fulfilled和从pending变成rejected。
3.Promise对象是一个构造函数,用来生成Promise实例,示例:
|
|
4.Promise示例生成后,可以用then方法分别指定resolved状态和rejected状态的回调函数。示例:
|
|
5.简单示例:
|
|
6.Promise新建后就会立即执行,示例:
|
|
7.异步加载图片的例子:
|
|
8.用Promise实现Ajax的例子:
|
|
Promise.prototype.then()
1.then方法是定义在原型对象Promise.prototype上的,作用是为Promise实例添加状态改变时的回调函数。
2.then方法返回的是一个新Promise实例,因此可以采用链式写法,即在then方法后面再调用另一个then方法。例如:
|
|
3.采用箭头函数简化上述代码:
|
|
Promise.prototype.catch
1.Promise.prototype.catch是.then(null, rejection)的别名,用于指定发生错误时的回调函数。例如:
|
|
2.then方法指定的回调函数如果在运行中抛出错误,也会被catch方法捕获。
3.reject方法的作用,等同于抛出错误,如果Promise状态已经变成resolved,再抛出错误是无效的。例如:
|
|
4.一般来说是不需要reject函数的,总是使用catch方法,例如:
|
|
5.Promise内部的错误不会影响到Promise外部的代码,不会终止脚本执行。
6.建议Promise对象后面要跟catch方法,catch方法返回的还是一个Promise对象,因此可以链式编程。
7.如果catch后面继续调用then方法,那么当这个then方法发生错误时,就不会被捕获。
Promise.all()
1.Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例。
|
|
2.Promise.all方法的参数可以不是数组,但必须有Iterator接口,且返回的每个成员都是Promise实例。
3.包装的新Promise实例的状态由p1、p2、p3决定,只有p1、p2、p3的状态都变成fulfilled的,p的状态才会变成fulfilled,只要p1、p2、p3中有一个是rejected,p的状态就变成rejected。
4.示例:
|
|
注:如果作为参数的Promise实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。
Promise.race()
1.Promise.race方法同样是将多个Promise实例,包装成一个新的Promise实例。
|
|
2.p1、p2、p3中只要有一个改变状态,p的状态就跟着改变。
3.示例:
|
|
Promise.resolve()
1.Promise.resolve方法将现有的对象转换为Promise对象
|
|
2.Promise.resolve方法的参数分成四种情况:
(1)参数是一个Promise实例,那么Promise.resolve将不做任何修改,直接返回。
(2)参数是一个thenable对象,thenable对象指的是具有then方法的对象,Promise.resolve方法会将这个对象转换为Promise对象,然后立即执行thenable的then方法。
(3)参数不具有then方法,或者就不是对象,Promise.resolve将返回一个新的Promise对象,状态为resolved
(4)不带参数时,直接返回一个Promise对象
Promise.reject()
1.Promise.reject()方法也会返回一个新的Promise实例,状态为rejected。例如:
|
|
2.Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。
3.示例:
|
|
两个有用的附加方法
1.done()
(1)Promise对象的回调链,不管以then方法或catch方法结尾,要是最后一个方法抛出错误,都有可能无法捕获到,因此我们可以提供一个done方法,总是处于回调链的尾端,保证抛出任何可能出现的错误。
(2)示例:
(3)done方法实现代码:
|
|
2.finally()
(1)finally方法用于指定不管Promise对象最后状态如何,都会执行的操作。
(2)示例:
(3)finally方法的实现代码:
|
|
应用
1.加载图片
|
|
Promise.try()
1.如果不知道函数是同步还是异步的,但是想用Promise来处理它,一般就会采用下面的写法:
|
|
2.如果函数是同步的,那么它会在本轮事件循环的末尾执行,例如:
|
|
3.Promise.try是模拟try代码块,就像promise.catch模拟的是catch代码块,例如:
|
|