目录
什么是 Promise
Promise 是 JavaScript 用来处理 异步操作(比如从服务器获取数据、读文件等)的一个工具,它能帮助你更好地处理 操作成功 或 失败 的结果。避免“回调地狱”(Callback Hell)的问题。
假设你有一个任务要做,它可能需要一点时间才能完成,比如下载文件。你不想让整个程序停下来等这个任务完成,而是希望继续做其他事情。这时,Promise 就非常有用,它可以在后台完成任务,同时你的代码仍然可以继续执行。
Promise 的三种状态
- Pending(待定):任务还在进行中,还没有成功也没有失败。
- Fulfilled(已完成):任务成功完成,得到了结果。
- Rejected(已拒绝):任务失败,产生了错误。
Promise 的 executor 执行器函数
Promise 构造方法接收一个执行器(executor)函数,执行器有两个函数参数:resolve() 和 reject()。
- resolve():表示操作成功,并给出结果,参数是任务的返回值。
- reject():表示操作失败,并给出错误信息,参数是错误对象。
示例: // 创建一个 Promise 对象
// 创建一个 Promise 对象
const myPromise = new Promise((resolve, reject) => {
let success = true; // 假设这是异步任务的返回结果,成功或者失败
if (success) {
resolve('Yes'); // 如果成功,调用 resolve,用于改变 Promise 的状态为 fulfilled(已完成),并传递成功的结果'Yes'。
} else {
reject('No'); // 如果失败,调用 reject,用于改变 Promise 的状态为 rejected(已失败),并传递失败的原因('No')。
}
});
Promise 的 then 函数
then 方法的作用是处理 Promise 对象在异步操作完成后的结果(then 就是处理 http 请求后的返回结果),允许你指定成功和失败的回调函数。它使得你能够处理异步操作的结果,并支持链式调用,将多个异步操作按顺序连接起来。
then 方法接收两个回调函数作为参数:
- onFulfilled():Promise 成功时调用的回调函数,接收成功的结果值。
- onRejected():Promise 失败时调用的回调函数,接收失败的原因。
then 的返回值:
- then 返回一个新的 Promise,这个返回的 Promise 会根据回调函数的执行结果(成功或失败)继续进行链式调用,并传递结果或错误。
示例: // 调用 Promise 对象
// 创建一个 Promise 对象
const myPromise = new Promise((resolve, reject) => {
let success = false; // 假设这是异步任务的返回结果,成功或者失败
if (success) {
resolve('Yes'); // 如果成功,调用 resolve,用于改变 Promise 的状态为 fulfilled(已完成),并传递成功的结果'Yes'。
} else {
reject('No'); // 如果失败,调用 reject,用于改变 Promise 的状态为 rejected(已失败),并传递失败的原因('No')。
}
});
// 调用 Promise 对象
myPromise
.then((result) => {
console.log(result); // 如果成功,打印:Yes
}, (err) => {
console.log(err); // 如果失败,打印:No
});
Promise 的 catch 函数
catch() 和 onRejected() 都是用来处理 Promise 失败(rejected)的情况,但它们有一些细微的区别。
- catch 是 Promise 的一个独立方法,专门用来捕获和处理 Promise 失败时的错误。
- 它通常用于链式调用中,处理 Promise 链中任何阶段的错误,而不仅仅是某个特定的 Promise。
- catch 也可以用于处理 then 链中的错误,而不仅仅是第一个 Promise。
- 如果你在 then 中没有处理 onRejected,那么你也可以在后续的 catch 中捕获错误。当然如果你处理了 onRejected,那么 catch 就不会再处理被你处理过的问题了。
catch 的语法:
promise.catch(onRejected);
等价于promise.then(null, onRejected);
示例: // catch 捕获 then 链中的异常
const myPromise = new Promise((resolve, reject) => {
reject('No');
});
// 调用 Promise 对象
myPromise
.then((result) => {
}, (err) => {
console.log(err); // 如果失败,打印:No
throw new Error("onRejected 中的错误");
})
.catch((err) => {
console.log("err = ", err); // catch 捕获 then 链中的异常
});
Promise 的链式调用
Promise 允许你将多个任务链在一起,这样可以依次处理多个异步操作。后面的链依赖前面链的返回结果。(Promise 的链式调用部分解决了回调地狱问题,但是回调的情况还是有些多,所以叫部分解决)
new Promise<number>((resolve) => resolve(1))
.then((result) => {
console.log(result); // 打印:1
return result + 1; // 返回新的值
})
.then((result) => { // 接收了上一个链的返回结果
console.log(result); // 打印:2
return result + 1; // 返回新的值
})
.then((result) => { // 接收了上一个链的返回结果
console.log(result); // 打印:3
});
Promise 的静态方法
Promise.all()
Promise.all() 方法接收一个包含多个 Promise 对象的数组,返回一个新的 Promise,这个新的 Promise 只有在数组中所有的 Promise 都成功时才会成功。如果数组中的某一个 Promise 失败,Promise.all() 立即返回失败的 Promise。
示例:
const p1 = new Promise((resolve, reject) => {
setTimeout(resolve, 5000, 1)
});
const p2 = Promise.resolve(2);
const p3 = Promise.resolve(3);
// 上面的 Promise 都执行了并且执行成功了,all 才能执行
Promise.all([p1, p2, p3])
.then((results) => {
console.log(results); // 5秒后打印:[1, 2, 3]
})
.catch((error) => {
console.log(error);
});
Promise.allSettled()
Promise.allSettled() 方法接收一个包含多个 Promise 对象的数组,返回一个新的 Promise,这个新的 Promise 只有在数组中所有的 Promise 都处理完成后返回,不论是成功还是失败。返回的数组包含每个 Promise 的结果(无论是 fulfilled 还是 rejected)。
示例:
const p1 = Promise.resolve(1);
const p2 = Promise.reject('Failed');
const p3 = Promise.resolve(3);
Promise.allSettled([p1, p2, p3])
.then((results) => {
console.log(results);
// [
// { status: 'fulfilled', value: 1 },
// { status: 'rejected', reason: 'Failed' },
// { status: 'fulfilled', value: 3 }
// ]
});
Promise.any()
Promise.any() 方法接收一个包含多个 Promise 的数组,返回第一个成功的 Promise,如果所有 Promise 都失败,它返回一个 AggregateError 错误。
示例:
const p1 = Promise.reject('Failed');
const p2 = Promise.resolve(2);
const p3 = Promise.reject('Another failure');
Promise.any([p1, p2, p3])
.then((result) => {
console.log(result); // 打印:2
})
.catch((error) => {
console.log(error);
});
Promise.race()
Promise.race() 方法接收一个包含多个 Promise 的数组,并返回第一个完成(无论是成功还是失败)的 Promise 结果。
示例:
const p1 = new Promise((resolve) => setTimeout(resolve, 5000, 'First'));
const p2 = new Promise((resolve) => setTimeout(resolve, 100, 'Second'));
Promise.race([p1, p2])
.then((result) => {
console.log(result); // 打印:Second
})
.catch((error) => {
console.log(error);
});