1. promise 介绍
它是一个对象,也就是说与其他JavaScript对象的用法,没有什么两样;其次,它起到代理作用(proxy),充当异步操作与回调函数之间的中介。它使得异步操作具备同步操作的接口,使得程序具备正常的同步运行的流程,回调函数不必再一层层嵌套。
它的思想是,每一个异步任务立刻返回一个Promise对象,由于是立刻返回,所以可以采用同步操作的流程。这个Promises对象有一个then方法,允许指定回调函数,在异步任务完成后调用。
2. promise 对象的三种状态
① 异步操作未完成(pending)
② 异步操作已完成(resolved)
③ 异步操作失败(rejected)
3. 工作过程
Promise对象使用then方法添加回调函数。then方法可以接受两个回调函数,第一个是异步操作成功时(变为resolved状态)时的回调函数,第二个是异步操作失败(变为rejected)时的回调函数(可以省略)。一旦状态改变,就调用相应的回调函数,这两个回调函数都接受异步操作传回的值作为参数。
4. then 的链式使用
① 首先then方法返回的一个新的promise对象,因此可以采用链式写法。
② then方法的第一个参数是Resolved状态的回调函数,第二个参数(可选)是Rejected状态的回调函数。
③ 如下,promise的状态一旦变为resolved,就依次调用后面每一个then指定的回调函数,每一步都必须等到前一步完成,才会执行。最后一个then方法的回调函数console.log和console.error,用法上有一点重要的区别。console.log只显示回调函数step3的返回值,console.error可以显示step1、step2、step3之中任意一个发生的错误,Promises对象的错误有传递性。
promise
.then(step1)
.then(step2)
.then(step3)
.then(
console.log,
console.error
);
5. promise 对象的使用
var promise = new Promise(function(resolve, reject) { // promise的构造函数,Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject
// 异步操作的代码
if (/* 异步操作成功 */){
resolve(value);//将异步的操作结果作为参数传递出去
} else {
reject(error);
}
});
其中resolve和reject它们是两个函数,由JavaScript引擎提供,不用自己部署。
resolve函数的作用:将Promise对象的状态从“未完成”变为“成功”(即从Pending变为Resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject函数的作用:将Promise对象的状态从“未完成”变为“失败”(即从Pending变为Rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
6.Promise.prototype.catch()
① 一个 Promise 对象,如果异步操作抛出错误,状态就会变为Rejected,就会调用catch方法指定的回调函数,处理这个错误。
promise.then(function(posts) {
// ...
}).catch(function(error) {
// 处理 getJSON 和 前一个回调函数运行时发生的错误
console.log('发生错误!', error);
});
② 另外,then方法指定的回调函数,如果运行中抛出错误,也会被catch方法捕获。
var promise = new Promise(function(resolve, reject) {
throw new Error('test');
});
promise.catch(function(error) {
console.log(error);
});
// Error: test
③ 另外两种写法
// 写法一
var promise = new Promise(function(resolve, reject) {
try {
throw new Error('test');
} catch(e) {
reject(e);
}
});
promise.catch(function(error) {
console.log(error);
});
// 写法二
var promise = new Promise(function(resolve, reject) {
reject(new Error('test'));//reject方法的作用,等同于抛出错误
});
promise.catch(function(error) {
console.log(error);
});
④ Promise 在resolve语句后面再抛出错误不会被捕获。因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了。
var promise = new Promise(function(resolve, reject) {
resolve('ok');
throw new Error('test');
});
promise
.then(function(value) { console.log(value) })
.catch(function(error) { console.log(error) });
// ok