一:什么是Promise
Promise是一个对象,它代表一个一步操作的最终完成或者是失败。它的then、catch、finally方法会返回一个新的Promise,这就是Promise很棒的一点---链式调用(chaining)。
二:Promise的三种状态
pending:进行中
fulfilled:已成功
rejected:已失败
1、一旦状态改变,就不能再发生变化
2、Promise对象的状态的改变,只能有两种:
pending ===> fulfilled
pending ===> rejected
三:Promise基本用法
创造一个Promise实例:
const promise = new Promise((resolve, reject) => {
if(/*异步操作成功*/) {
resolve(value);
} else {
reject(error);
}
});
Promise的两个参数:resolve和reject(两个函数)
resolve()
将Promise的状态从未完成(pending)变为成功(resolve),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject()
将Promise的状态从未完成(pending)变为失败(rejected),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去。
四:then 和 catch
const flag = 1;
const p = new Promise((resolve, reject) => {
if(flag) {
resolve(flag);
} else {
console.log('Error');
reject();
}
});
p.then(res => {
if(res) {
console.log('res', res);
}
}).catch(err => {
console.log('Promise is rejected now !!!', err);
}).finally(() => {
console.log('I am finally');
});
// 输出结果:
// res 1
// I am finally
上面代码中,p返回一个Promise对象,当flag为1时,状态就变为resolved,则会调用.then()方法指定的回调函数。
下述代码中,当flag为0时,状态就会变成rejected,则会调用.catch()方法指定的回调函数。
const flag = 0;
const p = new Promise((resolve, reject) => {
if(flag) {
resolve(flag);
} else {
console.log('Error');
reject();
}
});
p.then(res => {
if(res) {
console.log('res', res);
}
}).catch(err => {
console.log('Promise is rejected now !!!', err);
}).finally(() => {
console.log('I am finally');
});
// 输出结果:
// Error
// Promise is rejected now !!! undefined
// I am finally
上述两段代码,不管Promise的状态变成resolved还是rejected,finally()指定的回调函数都会被调用。
1、.then和.catch都会返回一个新的Promise
2、catch不管被连接到哪里,都能捕获上层未捕获过的错误。
3、.then、.catch中return一个error对象并不会抛出错误,所以不会被后续的.catch捕获。
4、.then和.catch返回的值不能是Promise,不然会造成死循环
5、.then方法是可以接收两个参数的,第一个是处理成功的函数,第二个是处理失败的函数,在某些时候可以认为catch是.then的第二个参数的简单写法。
// p是一个Promise
p.then()
五:finally
1、.finally()方法不管Promise对象最后的状态是什么,都会执行。
2、.finally()方法不接收任何参数,也就是说在finally中不知道Promise最终的状态是resolved还是rejected。
六:all和race
1. Promise.all()
Promise.all()方法用于将多个Promise实例,包装成一个新的Promise实例。
const p = Promise.all([p1, p2, p3]);
- 状态变化
(1)只有所有状态都变成fulfilled,p的状态才会变成fulfilled,p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
(2)只要其中有一个被rejected,p的状态就会变成rejected,第一个被reject的实例的返回值,会传递给p的回调函数。
const p1 = new Promise((resolve, reject) => {
resolve('hello');
}).then(result => result).catch(e => e);
const p2 = new Promise((resolve, reject) => {
throw new Error('I am rejected, but .then and .catch will return a new Promise!!');
}).then(result => result).catch(e => e);
Promise.all([p1, p2]).then(result => console.log(result)).catch(e => e);
// 输出结果
// ['hello','I am rejected, but .then and .catch will return a new Promise']
// p1:resolved, p2:reject,但是.catch返回了一个新的Promise,最后也会变成resolved,所以all的.then方法指定的回调函数会被调用
(3)如果p2没有自己的catch方法,就会调用Promise.all()的catch方法。
const p1 = new Promise((resolve, reject) => {
resolve('hello');
})
.then(result => result);
const p2 = new Promise((resolve, reject) => {
throw new Error('I am rejected, but .catch is not exist!!');
})
.then(result => result);
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// 输出结果
// Error: I am rejected, but .catch is not exist!!
// p2没有自己的catch,所以p2的错误会被Promise.all的catch捕获到
2.Promise.race()
Promise.race()的语法和all的差不多,都是将多Promise实例包装成一个新的Promise实例。
const p = Promise.race([p1, p2, p3]);
p1、p2、p3之中只要有一个实例率先改变状态,p的状态就会跟着变化,并且会吧率先改变的返回值传递给p的毁掉函数
七:Promise执行顺序问题
Promise新建之后就会立即执行
const promise = new Promise(function(resolve, reject) {
console.log('Promise');
resolve();
});
promise.then(function() {
console.log('resolved.');
});
console.log('Hi!');
// Promise Promise新建后立即执行
// Hi! 先执行同步任务
// resolved
Promise新建后立即执行,首先输出Promise,then方法指定的回调函数,将在当前脚本所有同步任务执行完成之后才会执行,所有resolved最后输出