Promise是一种异步编程的解决方案。
现在经常使用回调函数来解决异步通信(传参)的问题,若回调函数层次过深,就会出现回调地狱问题(逻辑不够清晰,可维护性差)
Promise是一个对象,通过new Promise来创建对象
1)Promise对象需要接收一个函数作为参数,这个作为参数的函数有两个参数,resolve,reject
2)resolve和reject本身也是函数
let p=new Promise((resolve,reject)=>{
});
Promise对象有三种状态:进行中(pending),成功(fullfilled)、失败(rejected)
Promise的状态有两种变化:
Pending---->成功
Pending—>失败
Promise状态一旦发生改变,这个状态就会凝固下来,(不能再改变了)
通过调用resolve函数,可以把promise由进行中修改为成功状态 resolved
通过调用reject函数,可以把promise由进行中修改为失败状态 rejected
调用resolve方法等价于调用then方法的第一个参数
调用了reject方法,等价于调用了then方法的第二个参数
1)then()方法
then方法可以接收两个函数作为参数,
第一个作为参数的函数:成功状态的回调
第二个作为参数的函数:失败状态的回调
注意:then方法会返回一个新的promise,由于返回值是promise,所以then方法可以实现连缀效果。then方法若只接收了一个参数,则这个参数是成功回调。
then方法的第一个参数函数的返回值问题:
1)若返回值是一个非promise,则这个数据会作为参数传递给第二个then
2)若返回值是一个promise,则第二个then状态的改变取决于这个promise
示例:利用promise解决异步回调问题
function fn(num) {
const p = new Promise((resolve, rejec) => {
setTimeout(() => {
console.log(num);
resolve();
}, 1000);
});
return p;
}
fn(1).then(() => {
return fn(2);
}).then(() => {
return fn(3);
}).then(() => {
console.log('over');
});
捕获,catch方法可以捕获promise执行过程中的错误,也可以捕获promise的失败状态
catch也需要接收一个参数作为参数
由于catch既可以接收promise的失败状态,又可以捕获promise中的代码异常信息,所以推荐:在then中接收成功结果,在catch中接收失败和异常结果
p.then(() => {
console.log('success');
}).catch(err => {
console.log(err);
});
不管promise的状态是成功还是失败,均会执行finally中的代码
all方法可以把多个promise实例包装成一个新的promise实例。
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
// reject(1);
}, 1000)
});
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2);
}, 2000)
});
// console.time();
const p = Promise.all([p1, p2]);
p.then(data=>{
console.log(data);
// console.timeEnd();
}).catch(err=>{
console.log(err);
});
总结:上面示例中,all方法将p1和p2封装为了一个新的promise示例,这个新的promise示例的状态取决于p1和p2的状态,分两种情况:
第一种情况:若p1和p2都变为成功状态,则新的promise也会变成成功状态,并且,会把p1和p2的成功的结果封装为数组在新的promise中收到
第二中情况:若p1或者p2有一个变为了失败状态,则新的promise会立即变为失败状态
race方法也会将多个promise封装为一个新的promise实例。新的promise实例的改变取决于最快发生改变的那个promise的状态。