👻认识promise作用
👻promise介绍
在 JavaScript 中,Promise 是一种强大的异步编程工具,它的作用在于处理异步操作,使得代码更>具可读性和可维护性。Promise 最早出现在 ECMAScript 6(ES6)中,它为开发者提供了一种更结>构化的方式来处理异步任务,尤其是网络请求、文件读写、定时任务等等。
👻Promise 主要作用
- 处理异步操作:Promise 可以用来处理异步操作,例如网络请求、文件读写、定时器等等。这有助于避免回调地狱(Callback Hell)和提高代码的可读性。
- 更好的错误处理:Promise 允许我们轻松地捕获和处理异步操作中的错误,而不需要使用传统的 try-catch 块。
- 链式调用:Promise 支持链式调用,可以按顺序执行一系列的异步操作,使代码看起来更加清晰。
👻promise基本使用
Promise 是一个代表异步操作最终完成或失败的对象。一个 Promise 可以处于以下三种状态之一:
- Pending(进行中):初始状态,表示异步操作还在进行中,尚未完成或失败。
- Fulfilled(已完成):表示异步操作已成功完成。
- Rejected(已失败):表示异步操作发生了错误或失败。
下面是一个基本的 Promise 示例:
javascript
const myPromise = new Promise((resolve, reject) => {
// 异步操作,例如发送网络请求
setTimeout(() => {
const randomNumber = Math.random();
if (randomNumber < 0.5) {
resolve("成功:数据加载完成");
} else {
reject("失败:数据加载失败");
}
}, 1000);
});
myPromise.then((result) => {
console.log(result); // 成功:数据加载完成
}).catch((error) => {
console.error(error); // 失败:数据加载失败
});
在这个示例中,创建了一个 Promise 对象 myPromise
,它模拟了一个异步操作。当异步操作完成时,调用 resolve
函数表示成功,调用 reject
函数表示失败。然后,使用 .then()
方法来处理成功的情况,使用 .catch()
方法来处理失败的情况。
👻promise的状态及状态变化
Promise 的三种状态:Pending(进行中)、Fulfilled(已成功)和Rejected(已失败)。这些状态是不可逆转的,一旦 Promise 进入了 Fulfilled 或 Rejected 状态,它将永远保持在这个状态,并且无法再次改变。
👻1. Pending(进行中)
Promise 最初的状态是 Pending,表示异步操作正在进行中,但尚未完成。在这个状态下,Promise 可以转换为 Fulfilled 或 Rejected 状态,取决于异步操作的结果。
👻2. Fulfilled(已成功)
当异步操作成功完成时,Promise 的状态将从 Pending 转换为 Fulfilled。这表示异步操作已成功,并且可以获取到结果值。
👻3. Rejected(已失败)
当异步操作由于某种原因失败时,Promise 的状态将从 Pending 转换为 Rejected。这表示异步操作已失败,并且可以获取到错误信息。
👻状态变化示例
下面是一个示例,演示了 Promise 的状态变化:
javascript
const successPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("成功结果");
}, 1000);
});
const failurePromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("失败原因"));
}, 1000);
});
successPromise
.then((result) =>
console.log("成功状态:", result);
})
.catch((error) => {
console.error("失败状态:", error.message);
});
failurePromise
.then((result) => {
console.log("成功状态:", result);
})
.catch((error) => {
console.error("失败状态:", error.message);
});
在上面的示例中,successPromise
成功完成,进入 Fulfilled 状态,并输出成功状态的结果。而 failurePromise
由于出错而进入 Rejected 状态,并输出失败状态的错误信息。
👻promise实例方法
Promise 提供了一系列实例方法,用于处理异步操作和状态变化。
👻1. then
方法
then
方法是 Promise 中最重要的方法之一,用于注册回调函数来处理异步操作的结果。它接受两个参数:onFulfilled
和 onRejected
,分别用于处理成功和失败的情况。
👻基本用法
javascript
const myPromise = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
resolve("数据加载完成"); // 成功时调用 resolve
// 或者
// reject(new Error("数据加载失败")); // 失败时调用 reject
}, 1000);
});
myPromise
.then((result) => {
console.log(result); // 成功:数据加载完成
})
.catch((error) => {
console.error(error.message); // 失败:数据加载失败
});
👻多次调用 then
同一个 Promise 实例可以调用多次 then
方法,当 Promise 中的 resolve
被回调时,所有 then
方法传入的回调函数都会被调用。
javascript
const promise = new Promise((resolve) => {
resolve("你好");
});
// 同时调用多个 then 方法
promise.then((res) => console.log(res));
promise.then((res) => console.log(res));
promise.then((res) => console.log(res));
👻then
方法回调函数的返回值
then
方法传入的回调函数可以有返回值。如果返回的是普通值,那么这个普通值将作为一个新的 Promise 的 resolve
的值。
javascript
const promise = new Promise((resolve) => {
resolve("你好");
});
promise.then(() => "then").then((res) => console.log(res)); // 打印 "then"
如果返回的是 Promise,那么就可以再次调用 then
方法。
javascript
const promise = new Promise((resolve) => {
resolve("你好");
});
promise
.then(() => {
return new Promise((resolve) => {
setTimeout(() => {
resolve("success");
}, 2000);
});
})
.then((msg) => {
// 2 秒后打印 "success"
console.log(msg);
});
如果返回的是一个对象,并且该对象实现了 thenable
,该 then
函数有两个参数 resolve
和 reject
,则 resolve
的值将会传递给下一个 Promise。
javascript
const promise = new Promise((resolve) => {
resolve("你好");
});
promise
.then(() => {
return {
then(resolve) {
return resolve("success");
},
};
})
.then((msg) => {
// 打印 "success"
console.log(msg);
});
👻2. catch
方法
除了通过 then
方法的第二个参数来捕获 reject
错误之外,还可以使用 catch
方法,它返回一个新的 Promise,用于处理 Promise 实例的错误。
javascript
const promise = new Promise((resolve, reject) => {
reject("error");
});
// 使用 catch 捕获错误
promise.catch((err) => {
console.error(err); // 打印 "error"
});
// 或者
promise
.then(() => {})
.catch((err) => {
console.error(err); // 打印 "error"
});
catch
方法也可以多次调用,只要 Promise 实例的状态为 rejected
,那么就会调用 catch
方法。
javascript
const promise = new Promise((resolve, reject) => {
reject("error");
});
// 这两个 catch 都会调用
promise.catch((err) => {
console.log(err);
});
promise.catch((err) => {
console.log(err);
});
👻3. finally
方法
finally
方法是 ES9(ES2018) 新增的特性,无论一个 Promise 实例是 fulfilled
还是 rejected
,finally
都会执行。它不接收任何参数。
javascript
const promise = new Promise((resolve, reject) => {
reject("error");
});
promise
.then((res) => {
console.log("res:", res);
})
.catch((err) => {
console.log("err", err);
})
.finally(() => {
console.log("finally code execute");
});
finally
方法适用于需要在不管 Promise 状态如何都要执行一些清理操作的场景。
👻promise的类方法
除了 Promise 实例方法,Promise 还提供了一些类方法,用于创建和处理多个 Promise 实例。
👻1. Promise.resolve()
Promise.resolve()
方法返回一个以给定值解析后的 Promise 对象。如果该值是一个 Promise,它将被返回原封不动(不进行解析)。
javascript
const resolvedPromise = Promise.resolve("解析成功");
const rejectedPromise = Promise.reject("解析失败");
resolvedPromise.then((result) => {
console.log(result); // 解析成功
});
rejectedPromise.catch((error) => {
console.error(error); // 解析失败
});
// 处理 Promise 实例
const originalPromise = new Promise((resolve) => {
resolve("原始 Promise");
});
const resolvedWithPromise = Promise.resolve(originalPromise);
resolvedWithPromise.then((result) => {
console.log(result); // 原始 Promise
});
👻2. Promise.reject()
Promise.reject()
方法返回一个带有拒绝原因的 Promise 对象。
javascript
const rejectedPromise = Promise.reject("拒绝原因");
rejectedPromise.catch((error) => {
console.error(error); // 拒绝原因
});
👻3. Promise.all()
Promise.all()
方法接受一个可迭代的对象,如数组或字符串,里面包含多个 Promise 对象,并返回一个新的 Promise 对象。这个新的 Promise 在所有输入的 Promise 都成功解析后才会解析,如果任何一个 Promise 被拒绝,它就会立即被拒绝。
javascript
const promise1 = Promise.resolve("第一个 Promise");
const promise2 = Promise.resolve("第二个 Promise");
const promise3 = Promise.reject("第三个 Promise");
Promise.all([promise1, promise2])
.then((results) => {
console.log(results); // ["第一个 Promise", "第二个 Promise"]
})
.catch((error) => {
console.error(error);
});
Promise.all([promise1, promise2, promise3])
.then((results) => {
console.log(results); // 这里不会执行,会立即被拒绝
})
.catch((error) => {
console.error(error); // 第三个 Promise 拒绝的原因
});
👻4. Promise.race()
Promise.race()
方法接受一个可迭代的对象,如数组或字符串,里面包含多个 Promise 对象,并返回一个新的 Promise 对象。这个新的 Promise 在第一个输入的 Promise 成功解析或拒绝后立即解析或拒绝。
javascript
const promise1 = new Promise((resolve) => {
setTimeout(() => {
resolve("第一个 Promise");
}, 1000);
});
const promise2 = new Promise((resolve) => {
setTimeout(() => {
resolve("第二个 Promise");
}, 500);
});
Promise.race([promise1, promise2])
.then((result) => {
console.log(result); // 第二个 Promise(因为它解析得更快)
})
.catch((error) => {
console.error(error);
});
👻Promise 链的执行
在 JavaScript 中,Promise 链是一种处理多个异步操作的方法,其中一个操作的结果将传递给下一个操作。这种方法使得异步操作能够按照预期的顺序执行,提高了代码的可读性和可维护性。
👻创建 Promise 链
Promise 链是通过在 then
方法中返回新的 Promise 来创建的。每次调用 then
方法都会返回一个新的 Promise,它可以用来定义下一个操作。
javascript
const initialPromise = someAsyncOperation();
initialPromise
.then((result) => {
// 第一个异步操作的结果
return anotherAsyncOperation(result); // 返回新的 Promise
})
.then((result) => {
// 第二个异步操作的结果
return yetAnotherAsyncOperation(result); // 返回新的 Promise
})
.then((finalResult) => {
// 最终的结果
console.log("最终结果:", finalResult);
})
.catch((error) => {
// 处理任何错误
console.error("错误:", error);
});
在上面的示例中,initialPromise
是一个异步操作的 Promise。我们通过 then
方法创建了一个 Promise 链。在每个 then
中,我们可以访问前一个操作的结果,并返回一个新的 Promise 来定义下一个操作。最后,使用 catch
方法来处理任何可能的错误。
👻Promise 链的执行顺序
Promise 链中的操作是按照顺序执行的,每个操作都在前一个操作成功完成后才会触发。这确保了异步操作的顺序性。
如果某个操作返回一个普通的值而不是 Promise,它将被包装成一个立即成功的 Promise,并立即传递给下一个操作。
javascript
const promiseChain = Promise.resolve(1)
.then((result) => {
console.log("第一步:", result);
return result + 1; // 返回一个新的值
})
.then((result) => {
console.log("第二步:", result);
return result * 2; // 返回一个新的值
})
.then((result) => {
console.log("第三步:", result);
throw new Error("出错了"); // 抛出一个错误
})
.catch((error) => {
console.error("捕获到错误:", error.message);
});
// 输出:
// 第一步: 1
// 第二步: 2
// 第三步: 4
// 捕获到错误: 出错了
👻异步操作的顺序性
Promise 链的执行顺序确保了异步操作的顺序性,即使异步操作本身具有不同的执行时间。
javascript
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
delay(1000)
.then(() => {
console.log("第一步完成");
return delay(2000); // 2 秒延迟
})
.then(() => {
console.log("第二步完成");
return delay(500); // 0.5 秒延迟
})
.then(() => {
console.log("第三步完成");
});
// 输出:
// 第一步完成
// 第二步完成
// 第三步完成
在上面的示例中,尽管每个 delay
函数具有不同的延迟时间,但它们仍然按照顺序执行。
👻Promise 链中的错误处理
如果任何一个异步操作失败(Promise 进入 Rejected 状态),错误会传递给最近 的 .catch()
方法进行处理。例如:
javascript
asyncOperation1()
.then((result1) => {
console.log(result1); // 操作 1 完成
return asyncOperation2(); // 返回第二个异步操作的 Promise
})
.then((result2) => {
console.log(result2); // 操作 2 完成
throw new Error("操作 3 失败"); // 手动抛出错误
})
.then((result3) => {
console.log(result3); // 不会执行到这里
})
.catch((error) => {
console.error("出错了:", error); // 出错了: Error: 操作 3 失败
});
在上面的示例中,第二个 .then()
方法手动抛出了一个错误,因此会触发 .catch()
方法来处理错误。