一、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。