返回
创建于
状态公开
答案是:可以。
你可以对同一个 Promise 对象多次使用 await,而且每一次都会得到相同的结果。
1. 核心原理
Promise 本质上是一个状态机。一旦它的状态从 pending(进行中)变为 fulfilled(成功)或 rejected(失败),这个状态就被“冻结”了。
- 第一次 await:如果 Promise 还没完成,代码会暂停等待;如果已经完成,直接取值。
- 后续 await:因为 Promise 的状态已经确定,它会立即返回之前存储的那个结果(或抛出之前的错误)。
2. 代码示例
1const myPromise = new Promise((resolve) => {
2 console.log("执行器运行...");
3 setTimeout(() => resolve("Success!"), 1000);
4});
5
6async function test() {
7 console.log("第一次开始");
8 const result1 = await myPromise; // 等待 1 秒
9 console.log("第一次结果:", result1);
10
11 console.log("第二次开始");
12 const result2 = await myPromise; // 立即获取结果,不会再次等待
13 console.log("第二次结果:", result2);
14}
15
16test();执行流程图解:
- **第一次
await**:发现 Promise 还在pending,于是等待 1 秒。 - **第二次
await**:发现 Promise 已经是fulfilled状态,直接从内存里取出"Success!",不会重新执行 Promise 内部的代码。
3. 注意事项
Promise 内部代码只执行一次
Promise 构造函数里的代码在创建时就会立即执行,且只会执行一次。多次 await 只是在多次读取结果,而不是多次触发逻辑。如果你需要多次执行逻辑(比如发送两次请求),你应该使用函数:
const fetchData = () => new Promise(...)。
错误处理
如果 Promise 最终进入了 rejected 状态,那么每一次 await 都会抛出相同的错误,你每次都需要用 try...catch 去捕获。
1const failedPromise = Promise.reject("Error!");
2
3async function run() {
4 try { await failedPromise; } catch (e) { console.log("捕获 1:", e); }
5 try { await failedPromise; } catch (e) { console.log("捕获 2:", e); }
6}4. 常见应用场景
这种特性通常用于缓存异步结果。
例如,你可以在应用启动时发起一个获取配置文件的请求:
- 模块 A
await这个 Promise 获取配置。 - 模块 B 稍后也
await这个同一个 Promise。 这样可以确保配置文件只被下载一次,但多个地方都能安全地获取到数据。
您是遇到了多次 await 导致逻辑重复触发的问题,还是想利用这个特性做数据缓存?