ES6之Promise
一、Promise含义
Promise是解决异步编程的一种方式,比传统的解决方案——回调(各部分之间耦合度较高,且不利于代码的阅读和维护)和事件监听(整个程序都变成事件驱动型,运行流程很不清晰)更合理,更强大。
Promise两大特点:
(1)对象的状态不受外界影响。Promise
对象代表一个异步操作,有三种状态:pending
(进行中)、fulfilled
(已成功)和rejected
(已失败),只有异步结果可以决定当前是哪种状态,其他任何操作都改变不了这个状态;
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise
对象的状态改变,只有两种可能:从pending
变为fulfilled
和从pending
变为rejected
。
Promise缺点:
(1)一旦建立一个Promise就会立即执行,无法中途取消;
(2)如果不设置回调函数,Promise内部抛出错误时,不会反应到外部;
(3)当处于pending状态时,无法得知当前进展到哪一个阶段(是刚刚开始还是即将结束阶段)
二、Promise的基本使用
Promise
构造函数接受一个函数作为参数,该函数的两个参数分别是resolve
和reject
。它们是两个函数,resolve
函数的作用是,将Promise
对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject
函数的作用是,将Promise
对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
下面创建了一个Promise实例
const promise = new Promise(function(resolve, reject) { // ... some code if (/* 异步操作成功 */){ resolve(value); } else { reject(error); } });
Promise
实例生成以后,可以用then
方法分别指定resolved
状态和rejected
状态的回调函数(即then方法接受两个参数,一个是异步成功后的回调函数,另一个是异步操作失败后的回调函数,第二个参数是可选的,不一定要提供)。
promise.then(function(value) { // 异步操作成功后进行的回调操作 }, function(error) { // 异步操作失败后进行的回调操作 });
举个列子
new Promise(function (resolve,reject) { console.log(2); resolve(); //将Promise的状态从“未完成”变成“成功” }).then(function() { console.log(4); //成功时 },function(){ console.log(6); //失败时 }); // 结果是2,4 new Promise(function (resolve,reject) { console.log(2); reject(); //将Promise的状态从“未完成”变成“ 失败” }).then(function() { console.log(4); //成功时 },function(){ console.log(6); //失败时 }); // 结果是2,6
Promise 新建后就会立即执行。
let promise = new Promise(function(resolve, reject) { console.log('Promise'); resolve(); }); promise.then(function() { console.log('resolved.'); }); console.log('Hi!'); // Promise // Hi! // resolved
三、Promise.prototype.then()
Promise 实例具有then
方法,then
方法是定义在原型对象Promise.prototype
上的。它的作用是为 Promise 实例添加状态改变时的回调函数。前面说过,then
方法的第一个参数是resolved
状态的回调函数,第二个参数(可选)是rejected
状态的回调函数。
四、Promise.prototype.catch()
Promise.prototype.catch
方法是.then(null, rejection)
或.then(undefined, rejection)
的别名,用于指定发生错误时的回调函数。
举个栗子~
const promise = new Promise(function(resolve, reject) { throw new Error('test'); }); promise.catch(function(error) { console.log(error); }); // Error: test
reject
方法的作用,等同于抛出错误~
五、Promise.prototype.finally()
finally
方法用于指定不管 Promise 对象最后状态如何(成功或失败),都会执行的操作。该方法是 ES2018 引入标准的。
六、Promise.all()
Promise.all
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。Promise.all
方法接受一个数组作为参数,p1
、p2
、p3
都是 Promise 实例,如果不是,就会先调用Promise.resolve
方法,将参数转为 Promise 实例,再进一步处理。
const p = Promise.all([p1, p2, p3]);
p
的状态由p1
、p2
、p3
决定,分成两种情况。
(1)只有p1
、p2
、p3
的状态都变成fulfilled
,p
的状态才会变成fulfilled
,此时p1
、p2
、p3
的返回值组成一个数组,传递给p
的回调函数。
(2)只要p1
、p2
、p3
之中有一个被rejected
,p
的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给p
的回调函数。
七、Promise.race()
Promise.race
方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.race([p1, p2, p3]);
Promise.race与Promise.all的参数都是数组,不同的是,Promise.race()只要p1
、p2
、p3
之中有一个实例率先改变状态,p
的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p
的回调函数。而Promise.all是只要有一个Promise失败,则该Promise.all失败,返回第一个子Promise的失败结果,当所有的状态都变成fulfilled时,Promise.all状态才绘变成fulfilled,并转给回调函数。
八、Promise.resolve()
将现有对象转为 Promise 对象
九、Promise.reject()
Promise.reject(reason)
方法也会返回一个新的 Promise 实例,该实例的状态为rejected
。