Promise 核心机制与常用方法详解
本文系统梳理 JavaScript 中 Promise 的核心用法,详细解析 then、catch、finally 链式调用的状态传递机制,以及 Promise.all 和 Promise.race 的组合策略。同时涵盖 Promise.resolve 与 Promise.reject 的转换规则,帮助开发者掌握异步处理的最佳实践。
Promise 基础链式调用:then、catch 与 finally
then
在 then 方法中,可以通过 return 语句返回另一个 Promise 对象。
const p1 = new Promise((resolve, reject) =>{
resolve('p1')
})
const p2 = new Promise((resolve, reject) =>{
setTimeout(() =>{
resolve('p2')
},3000)
})
p1.then(res => {
console.log(res)
return p2
}).then(res =>{
// p2 resolve后才执行
console.log(res)
})
//p1
// 3s后输出...
// p2
此时,当前 Promise(如 p1)的状态将被新返回的 Promise(如 p2)所取代。只有当这个新的 Promise(p2)状态发生修改后,链式调用中的下一个 then 才会执行。
catch
1. 作用
catch 方法用于捕获 Promise 执行过程中抛出的错误,其功能等同于调用 .then(null, rejection) 或 .then(undefined, rejection)。
2. 可以获取到的错误
首先,它可以捕获 Promise 构造函数内部直接抛出的错误。需要注意的是,如果在 Promise 已经 resolve 之后才抛出错误,则该错误不会被 catch 捕获。
const p1 = new Promise((resolve,reject) => {throw new Error('error')})
p1.catch(error => console.log(error)) // Error: error
其次,它也能处理 Promise 显式调用 reject 操作时传递的错误。
const p2 = new Promise((resolve,reject) => reject('rejected'))
p2.catch(error => console.log(error)) // rejected
此外,如果 then 方法的回调函数中抛出了错误,catch 同样可以捕获到。
const p3 = new Promise((resolve,reject) => resolve('resolved'))
p3.then(res =>{
throw new Error('error')
}).catch(error => console.log(error)) // Error: error
最后,如果 then 方法返回了一个新的 Promise(且该链中未定义 catch 方法),而新 Promise 内部发生了 reject 或抛出错误,这些错误也会被当前的 catch 捕获。
3. 推荐使用 catch 方式捕获错误,而不是 then 的第二个参数:
主要原因是 catch 能够捕获到它前面所有 then 方法中发生的错误,而 then 的第二个参数仅能捕获紧邻的前一个 then 的错误,覆盖范围有限。
finally
- 无论 Promise 最终状态是 fulfilled 还是 rejected,finally 中的操作都会执行。
- finally 方法不接受参数,因此无法直接获取当前 Promise 的最终状态值。
Promise 组合方法:all 与 race
Promise.all
1. 参数
Promise.all 的参数不仅可以是数组,任何具有 Iterator 接口的对象都可以作为参数传入。如果参数是数组,其每个元素都应为 Promise 实例;如果不是,则会通过 Promise.resolve 将其转换为 Promise 实例。
const obj = {
[Symbol.iterator]() {
let index = 0
return {
next() {
return {
// promise对象 和 其他类型都可以
value: new Promise(resolve => resolve(index++)), done: index > 2
// value: index++, done: index > 2
}
}
}
}
}
const p = Promise.all(obj)
p.then(res => {
console.log(res) // [0, 1]
})
2. 状态
const p = Promise.all([p1, p2, p3]);
Promise.all 返回的 Promise(p)的状态取决于所有传入的 Promise(如 p1、p2、p3)的状态,具体分为两种情况:
- 只有当 p1、p2、p3 的状态全部变为 fulfilled 时,p 的状态才会变为 fulfilled。此时,p1、p2、p3 的返回值会组成一个数组,传递给 p 的回调函数。
- 只要 p1、p2、p3 中有一个实例被 rejected,p 的状态就会立即变为 rejected。此时,第一个被 reject 的实例的返回值,会传递给 p 的回调函数。
3. catch
如果参数中的某个 Promise 已经定义了 catch 方法,那么 Promise.all() 自身的 catch 将不会捕获到该错误。
Promise.race
- 只要 p1、p2、p3 中有一个实例率先改变状态,p 的状态就会随之改变。那个率先改变的 Promise 实例的返回值,将传递给 p 的回调函数。
- Promise.race 的参数要求和 catch 规则与 Promise.all 相同。
Promise 静态转换方法:resolve 与 reject
Promise.resolve
该方法用于将现有对象转换为 Promise 对象。
1. 参数
- 如果参数是一个 Promise 实例,Promise.resolve 将原封不动地返回这个实例。
- 如果参数是一个 thenable 对象(即具有 then 方法的对象),Promise.resolve 会将其转换为 Promise 对象,并立即执行它的 then 方法。
- 如果参数不是 thenable 对象,或者是一个原始值,Promise.resolve 会返回一个新的 Promise 对象,其状态为 resolved。
- 如果 Promise.resolve 没有参数,它将直接返回一个处于 resolved 状态的 Promise 对象。
Promise.reject
该方法返回一个状态为 rejected 的 Promise 实例。
Promise.reject() 方法的参数会原封不动地作为 reject 的理由,并作为后续错误处理方法的参数传递。
const thenable = {
then(resolve, reject) {
reject('error');
}
};
Promise.reject(thenable)
.catch(e => {
console.log(e === thenable)
})
// true e并不是'error'
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
D3.js 比例尺与坐标轴的配置详解
2026-11-05 16:54:46
JavaScript怎么遍历对象的Symbol键和不可枚举属性
2026-11-05 13:13:39
封装一个健壮的JS字符串判空工具函数
2026-11-05 12:16:14
JavaScript合并数组的三种常用方法:concat、扩展运算符与push
2026-11-05 11:22:29
JavaScript立即执行函数(IIFE)是什么及基本语法
2026-11-05 10:51:19
