介绍
-
三种状态
- pending 等待
- fulfilled 成功
- rejected 失败
-
实例的两个过程
- pending -> fulfilled : Resolved(已完成)
- pending -> rejected:Rejected(已拒绝)
-
实例方法
- then
状态发生改变的时候触发。两个参数。第一个参数是resolve的时候走,第二个参数是reject的时候触发 - catch 一个参数,功能类似then第二个参数
- finally 没有参数,失败成功都会触发
- then
then示例
const p = new Promise((resolve, reject)=>{
const flag = true; // false
if(flag) {
resolve('成功')
} else {
reject('err')
}
})
p.then(
(res) => {
console.log(res, 'then里面resolve成功的时候触发');
},
(err) => {
console.log(err, 'then里面reject失败的时候触发');
}
);
// flag为true打印结果: 成功 then里面resolve成功的时候触发
// flag为false打印结果: err then里面reject失败的时候触发
.catch示例
const p = new Promise((resolve, reject)=>{
reject('err')
})
p.then(
(res) => {
console.log(res, 'then里面resolve成功的时候触发');
}).catch((err) => {
console.log(err, 'catch里面的失败');
});
// 打印结果 err catch里面的失败
.finally示例
const p = new Promise((resolve, reject) => {
resolve('成功');
// reject('err');
});
p.then((res) => {
console.log(res, 'then里面resolve成功的时候触发');
})
.catch((err) => {
console.log(err, 'catch里面的失败');
})
.finally(() => {
console.log('finally执行');
});
// 不管resolve还是reject每次执行都会打印finally执行
-
静态方法
- Promise.resolve()
返回一个Promise实例,状态成功 - Promise.reject()
返回一个Promise实例,状态失败 - Promise.all()全部
失败: 有一个promise失败,则失败,返回最快执行出失败的promise
成功:所有都执行成功,则成功,返回最后执行出成功的promise-
Promise.race() 赛跑
数组里最快改变状态的promise,就会影响Promise.race状态改变。
-
Promise.allSettled() 所有都完结
不会失败
数组里的promise实例全部改变状态就成功。返回数组,包含每一个示例的状态和返回结果 -
Promise.any()任一
与数组的some方法类似,每个执行一下。
成功:有一个成功,则成功,成功返回成功最快的promise值
失败:所有都失败,则失败,返回AggregateError: All promises were rejected
- Promise.resolve()
all示例
const p1 = Promise.resolve('p1');
const p2 = Promise.resolve('p2');
const p3 = Promise.reject('p3');
const p4 = Promise.reject('p4');
Promise.all([p1, p2, p3, p4])
.then((res) => {
console.log(res, 'then的res');
})
.catch((err) => {
console.log(err, 'catch的err');
})
.finally(() => {
console.log('执行了finally');
});
// 实际返回p3, .catch执行,finally执行
实战
- 并发
场景:两个请求,要同时发起,这时可以使用Promise.all([处理1,处理2]) - 控制并发分批处理接口
场景:假设有100个请求,每次发送3个请求,其中一个请求完毕,再加入新的请求,直到全部请求完毕。
这时如果使用promsie.all,浏览器会同时发送100个请求,这样可能会造成请求阻塞、页面卡顿、甚至服务器崩溃,显然不合理;
直接上代码
//自定义模拟请求函数
const request = url => {
return new Promise(resolve => {
setTimeout(() => {
resolve(`任务${url}完成`)
}, 1000)
}).then(res => {
console.log('执行完成功任务以后外部逻辑', res);
})
}
// 执行任务
async function fn(max = 5){
const urls = Array.from({length: 100}).map((item, index) => `url${index + 1}`)
const pool = [] // 并发池
for(let i=0; i<urls.length; i++){
let url = urls[i]
let task = request(url); // 当前执行的任务
task.then((data)=>{
//每当并发池跑完一个任务,从并发池删除个任务
pool.splice(pool.indexOf(task), 1)
console.log(`${url} 结束`);
})
pool.push(task);
if(pool.length === max){
//利用Promise.race方法来获得并发池中某任务完成的信号
//跟await结合当有任务完成才让程序继续执行,让循环把并发池塞满
await Promise.race(pool)
}
}
}
fn(5) // 打印结果,5个一组5个一组执行完毕打印