Promise 是 JavaScript 中的一种异步编程的解决方案。它代表了一个可能还未完成的操作的最终完成(或者失败)以及其结果值的表示。通过 Promise,你可以更清晰地处理异步操作(例如,网络请求、文件读取等),避免“回调地狱”问题,提升代码的可读性和维护性。
Promise 的基本概念
Promise 有三个状态:
- Pending(待定):初始状态,表示异步操作尚未完成。
- Fulfilled(已完成):表示异步操作已完成,成功返回结果。
- Rejected(已拒绝):表示异步操作失败,返回失败的原因。
Promise 构造函数
Promise 是一个构造函数,它接受一个执行器函数作为参数,执行器函数有两个参数:resolve 和 reject。
javascriptCopy Code
let promise = new Promise(function(resolve, reject) {
// 异步操作代码
let success = true; // 模拟异步操作结果
if (success) {
resolve("操作成功!"); // 操作成功时调用 resolve
} else {
reject("操作失败!"); // 操作失败时调用 reject
}
});
Promise 的基本用法
你可以通过 .then() 和 .catch() 来处理 Promise 的结果或错误:
.then(onFulfilled, onRejected):在Promise完成时调用onFulfilled,如果失败则调用onRejected。.catch(onRejected):用于捕获Promise的错误。
javascriptCopy Code
// 示例:一个简单的 Promise
let myPromise = new Promise((resolve, reject) => {
let success = true;
if (success) {
resolve("操作成功!");
} else {
reject("操作失败!");
}
});
myPromise
.then((result) => {
console.log(result); // 操作成功时执行
})
.catch((error) => {
console.error(error); // 操作失败时执行
});
示例:用 Promise 封装异步操作
假设你要进行一个异步操作,例如模拟读取文件内容。你可以用 Promise 来封装这个操作,处理成功或失败的情况。
javascriptCopy Code
function readFile(filePath) {
return new Promise((resolve, reject) => {
// 模拟读取文件的操作
setTimeout(() => {
if (filePath === "validFile.txt") {
resolve("文件内容:Hello World!");
} else {
reject("文件不存在!");
}
}, 1000); // 模拟异步操作延迟
});
}
readFile("validFile.txt")
.then((data) => {
console.log("文件读取成功:", data);
})
.catch((error) => {
console.error("文件读取失败:", error);
});
Promise 链式调用
Promise 支持链式调用,也就是说你可以通过连续的 .then() 方法来处理多个异步操作。
javascriptCopy Code
let promise = new Promise((resolve, reject) => {
resolve(10);
});
promise
.then((result) => {
console.log(result); // 输出: 10
return result * 2;
})
.then((result) => {
console.log(result); // 输出: 20
return result * 3;
})
.then((result) => {
console.log(result); // 输出: 60
});
Promise.all()
Promise.all() 方法接受一个包含多个 Promise 实例的数组,并返回一个新的 Promise,该 Promise 在所有输入的 Promise 都完成时才会完成。如果其中任何一个 Promise 被拒绝,Promise.all() 将立即失败。
javascriptCopy Code
let promise1 = new Promise((resolve) => setTimeout(resolve, 1000, "结果1"));
let promise2 = new Promise((resolve) => setTimeout(resolve, 2000, "结果2"));
let promise3 = new Promise((resolve) => setTimeout(resolve, 3000, "结果3"));
Promise.all([promise1, promise2, promise3])
.then((results) => {
console.log(results); // 输出: ["结果1", "结果2", "结果3"]
})
.catch((error) => {
console.error(error); // 如果任何一个 Promise 被拒绝,这里会捕获到
});
Promise.race()
Promise.race() 方法也接受一个包含多个 Promise 实例的数组,但是它返回一个新的 Promise,并且会以第一个完成的 Promise 的结果(无论是成功还是失败)为结果。
javascriptCopy Code
let promise1 = new Promise((resolve) => setTimeout(resolve, 3000, "结果1"));
let promise2 = new Promise((resolve) => setTimeout(resolve, 2000, "结果2"));
let promise3 = new Promise((resolve) => setTimeout(resolve, 1000, "结果3"));
Promise.race([promise1, promise2, promise3])
.then((result) => {
console.log(result); // 输出: "结果3"(因为它是第一个完成的)
})
.catch((error) => {
console.error(error);
});
Promise.allSettled()
Promise.allSettled() 方法接受一个 Promise 数组,返回一个新的 Promise,这个 Promise 会在所有的 Promise 完成后(无论是成功还是失败)返回一个数组,其中每个元素表示对应 Promise 的状态和结果。
javascriptCopy Code
let promise1 = Promise.resolve("成功");
let promise2 = Promise.reject("失败");
Promise.allSettled([promise1, promise2])
.then((results) => {
console.log(results);
// 输出:
// [
// { status: 'fulfilled', value: '成功' },
// { status: 'rejected', reason: '失败' }
// ]
});
async / await
async 和 await 是基于 Promise 的语法糖,简化了异步操作的写法。async 用于声明一个异步函数,await 用于等待一个 `Promise [Something went wrong, please try again later.]