参考学习文章
JS系列 (十一) - Promise用法的详细解析
一. 同步和异步的执行顺序
- 同步任务
(按照顺序一个一个执行)
示例:
console.log('任务1:同步')
console.log('任务2:同步')
console.log('任务3:同步')
============输出:
任务1:同步
任务2:同步
任务3:同步
- 异步任务
(按照顺序执行的过程中, 但遇到异步任务时,会继续执行下一个,等到异步任务完成时,异步才会再添加到主程序中执行. )
示例:
console.log('任务1:同步')
console.log('任务2:同步')
setTimeout(function (){
console.log('任务4:异步')
}) //不写定时器时间,默认为最小时间
console.log('任务3:同步')
============输出:
任务1:同步
任务2:同步
任务3:同步
任务4:异步
二. promise
多层异步函数循环调用的现象
setTimeout(function (){
console.log('任务4:异步')
console.log('任务3:同步')
setTimeout(function (){
console.log('任务5:异步')
console.log('任务6:异步')
})
})
作用
为了解决多层异步函数的嵌套问题, 需要用到 Promise使用
const p1 = new Promise((resolve, reject) => {
resolve(成功)
reject(失败)
})
p1.then(data => {
console.log(data) // ---->输出:成功后的数据
}).catch(err => {
console.log(err) // ---->输出:失败后的数据
})
| 方法 | 含义 |
|---|---|
| then | 成功后 只要是成功的状态(fulfilled)就自动调用 |
| catch | 失败后 rejected 状态就自动调用 |
| finally | 都会执行 无论失败与否,最后都会执行 |
- 解决嵌套
const p1 = new Promise((resolve, reject) => {
resolve("任务1成功后的数据")
// reject("任务1失败后的数据")
}).then(data => {
// 这里的 data = "任务1成功后的数据"
console.log(data)
return new Promise(((resolve, reject) => {
resolve("任务2成功后的数据")
}))
})
.then(data1 => {
// 这里的 data1 = "任务2成功后的数据"
console.log(data1)
})
.catch(err => {
console.log(err)
})
4. Promise类方法
4.1 resolve方法 和 reject 方法
使用类方法将值直接转为Promise来使用:
- Promise.resolve 方法来表完成.
- Promise.reject 方法来表拒绝.
Promise.resolve("why")
// 相当于
new Promise((resolve) => resolve("why"))
Promise.reject("why")
// 相当于
new Promise((resolve, reject) => reject("why"))
4.2 Promise.all
将多个Promise包裹在一起形成一个新的Promise;新的Promise状态由包裹的所有Promise共同决定:
- 当所有的Promise状态变成fulfilled状态时,新的Promise状态为fulfilled,并且会将所有Promise的返回值组成一个数组;
- 当有一个Promise状态为reject时,新的Promise状态为reject,并且会将第一个reject的返回值作为参数;
总结: 全成功才输出 resolve 数组, 有一个输出失败就会输出reject 项
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("111")
}, 1000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("222")
}, 2000);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("333")
}, 3000);
})
Promise.all([p1, p2, p3]).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
// 运行结果:3秒后输出 ["111", "222", "333"]
4.3. allSettled方法
该方法会在所有的Promise都有结果(settled),无论是fulfilled,还是reject时,才会有最终的状态;
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("111")
}, 1000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("err 222")
}, 2000);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("333")
}, 3000);
})
Promise.allSettled([p1, p2, p3]).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
打印输出结果res:
[
{ status: 'fulfilled', value: '111' },
{ status: 'rejected', reason: 'err 222' },
{ status: 'fulfilled', value: '333' }
]
4.4. race方法
race是竞技、竞赛的意思,表示多个Promise相互竞争,谁先有结果,那么就使用谁的结果.
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("111")
}, 1000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("err 222")
}, 2000);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("333")
}, 3000);
})
Promise.race([p1, p2, p3]).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
// 打印: "111"
4.5 any方法
any方法会等到一个fulfilled状态,才会决定新Promise的状态;
如果所有的Promise都是reject的,那么也会等到所有的Promise都变成rejected状态;
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("111")
}, 1000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("err 222")
}, 2000);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("333")
}, 3000);
})
Promise.any([p1, p2, p3]).then(res => {
console.log(res)
}).catch(err => {
console.log("err:", err)
})