一、Promise要点
-> js中,只有Promise对象才可以使用.then().catch()方法。
-> axios可以使用.then().catch(),完全是因为调用axios(),返回的是一个Promise对象。
-> new Promise() 里面的代码是同步代码,一旦调用promise对象就会立即执行new Promise()里的代码。
-> 只有.then().catch()里面的回调函数才是异步代码
二、Promise的3种状态
1、作用:了解Promise对象如何关联的处理函数,以及代码执行顺序
2、一个Promise对象,必然处于以下几个状态之一:
pending:初始状态,页面一旦调用Promise对象,Promise对象就会立刻处于pending状态
fulfilled:意味着操作成功完成
rejected:意味着操作失败完成
3、注意⚠️:
Promise对象的状态一旦是fulfilled或者rejected,状态就无法再被改变,也就是说一旦是fulfilled状态,就无法再改为rejected状态。
->调用了resolve(),把状态改成了fulfilled,then()里面的代码就会自动执行.
->调用了reject(),把状态改成了rejected,catch()里面的代码就会自动执行.
例如:如果代码里同时写了resolve(3); reject(4); 最后只会执行resolve()方法,不会执行reject()方法。这就是Promise对象的状态一旦是fulfilled或者rejected,状态就无法再被改变。
![](https://i-blog.csdnimg.cn/blog_migrate/d866e7b4c1b66730c400a918b7396cba.png)
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
//reject(2);
}, 3000);
});
console.log(p);
p.then(data => {
console.log(data);
}).catch(error => {
console.log("我是Promise错误", error);
})
一运行js,js会马上打印p对象,如果此时3秒内立马点击控制台的Promise对象,就是处于pending状态。也就是说,页面一旦调用Promise对象,Promise对象就会立刻处于pending状态。
![](https://i-blog.csdnimg.cn/blog_migrate/303df06eb7ebc3838b0425b147f7ab63.jpeg)
就算3秒后setTimeout运行完了,也依然是pending状态。
![](https://i-blog.csdnimg.cn/blog_migrate/321a3198e8e907d6524f0328a7769924.jpeg)
只有当3秒后setTimeout运行完了,你再点击控制台的Promise对象,才会显示对应的fulfilled或者rejected状态。
![](https://i-blog.csdnimg.cn/blog_migrate/c08394d4700dfc8c80b6b83fa14ca4b4.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/278754427292e35882cc3885c15d896d.jpeg)
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(3);
reject(4);
}, 3000);
});
console.log(p);
p.then(data => {
console.log(data);
}).catch(error => {
console.log("我是Promise错误", error);
})
如果代码里同时写了resolve(3); reject(4); 最后只会执行resolve()方法,不会执行reject()方法。这就是Promise对象的状态一旦是fulfilled或者rejected,状态就无法再被改变。
![](https://i-blog.csdnimg.cn/blog_migrate/7f3ccaca454e42679c78cf9ea7ae8c2f.jpeg)
三、Promise的链式调用
解决回调函数地狱问题
做法:在每一个.then()方法里面return一个Promise对象
new Promise((resolve, reject) => {
resolve(1);
}).then(res => {
console.log(res); // 1
return new Promise((resolve, reject) => {
resolve(res + 2);
})
}).then(res => {
console.log(res); // 3
return new Promise((resolve, reject) => {
reject(res + 2);
})
}).then(res => {
console.log(res); // 因为上面有reject,所以这里不会再执行
}).catch(error => {
// 上面任意一个promise对象发生错误都会在这里进行捕获
// 一旦发生reject,后面的promise对象的.then()将不会再执行
console.log("error", error); // error 5
})
上面的代码相当于下面这样写:
const a1 = new Promise((resolve, reject) => {
resolve(1);
});
const a2 = a1.then(res => {
console.log(res); // 1
return new Promise((resolve, reject) => {
resolve(res + 2);
});
});
const a3 = a2.then(res => {
console.log(res); // 3
return new Promise((resolve, reject) => {
resolve(res + 2);
});
});
const a4 = a3.then(res => {
console.log(res); // 5
});
四、Promise.all()
Promise的静态方法 Promise.all()
作用:高并发处理,同时发送请求,可以做到在所有请求都得到结果后再统一渲染页面数据
语法:Promise.all([p1, p2, p3, p4]) all方法里传一个数组,数组由多个Promise对象组成
返回结果:会返回一个新的Promise对象,.then()得到的结果是all()方法里多个Promise对象的结果组成的数组,.catch()方法里只要有一个请求发生错误就会走catch
const p1 = axios({
url: 'http://hmajax.itheima.net/api/weather',
params: {
city: '110100'
}
})
const p2 = axios({
url: 'http://hmajax.itheima.net/api/weather',
params: {
city: '110100'
}
})
const p3 = axios({
url: 'http://hmajax.itheima.net/api/weather',
params: {
city: '110100'
}
})
const result = Promise.all([p1, p2, p3]).then(res => {
console.log(res);
}).catch(error => {
// 只要有一个请求发生错误就会走catch
console.log(error);
})