如何让Promise等待广播触发?现有实现失效,求解决方案代码
Hey there! Let's sort out why your broadcast promise isn't waiting like you expect. The core idea of holding onto the promise's resolve/reject functions is totally valid, but there are a few common gotchas that might be messing things up. Let's fix this together.
Common Reasons Your Current Code Isn't Working
- If you're awaiting
broadcastPromisebefore callingbroadcast(), the promise will stay pending forever (you can't retroactively resolve a promise you already started waiting on). - Promises are one-time-only: once
broadcastPromiseis resolved, it stays in that state forever. If you try to wait on it again, it'll immediately return the old resolved value instead of waiting for a new broadcast. - Scope issues with
promiseFunctionsmight mean yourbroadcast()method isn't accessing the correct resolve function.
Solution: Encapsulated Deferred Promise
Let's wrap this logic in a reusable structure that handles creating fresh pending promises each time you need to wait for a broadcast. This avoids the one-time promise problem and keeps your scope clean.
Class-Based Implementation (Cleanest for Reusability)
class BroadcastWaiter { constructor() { // Initialize the first pending promise this.resetPromise(); } // Creates a new pending promise and stores its resolve/reject functions resetPromise() { this.promiseHandlers = {}; this.currentPromise = new Promise((resolve, reject) => { this.promiseHandlers.resolve = resolve; this.promiseHandlers.reject = reject; }); } // Triggers the broadcast, resolving the current pending promise broadcast(broadcastValues) { this.promiseHandlers.resolve(broadcastValues); // Reset immediately so the next wait gets a fresh promise this.resetPromise(); } // Waits for the next broadcast to fire async waitForBroadcast() { return await this.currentPromise; } }
How to Use This
// Set up the waiter const broadcastWaiter = new BroadcastWaiter(); // Example function that waits for a broadcast async function handleBroadcast() { console.log("Waiting for broadcast to arrive..."); const data = await broadcastWaiter.waitForBroadcast(); console.log("Received broadcast data:", data); } // Start waiting for the first broadcast handleBroadcast(); // Trigger the broadcast after 2 seconds setTimeout(() => { broadcastWaiter.broadcast({ status: "success", message: "First broadcast!" }); }, 2000); // Wait for a second broadcast later setTimeout(() => { handleBroadcast(); }, 3000); // Trigger the second broadcast setTimeout(() => { broadcastWaiter.broadcast({ status: "success", message: "Second broadcast!" }); }, 5000);
Plain Object Alternative (No Classes)
If you prefer not to use classes, you can achieve the same with a plain object:
const broadcastWaiter = { resetPromise() { this.promiseHandlers = {}; this.currentPromise = new Promise((resolve, reject) => { this.promiseHandlers.resolve = resolve; this.promiseHandlers.reject = reject; }); }, broadcast(broadcastValues) { this.promiseHandlers.resolve(broadcastValues); this.resetPromise(); }, async waitForBroadcast() { return await this.currentPromise; } }; // Initialize the first promise broadcastWaiter.resetPromise(); // Same usage as the class version async function handleBroadcast() { console.log("Waiting..."); const data = await broadcastWaiter.waitForBroadcast(); console.log("Got data:", data); } handleBroadcast(); setTimeout(() => broadcastWaiter.broadcast("Simple broadcast message"), 2000);
Why This Works
- Every time you call
waitForBroadcast(), it's attached to a fresh pending promise (unless a broadcast is already in progress). - After resolving a promise, we immediately reset it, so subsequent waits don't get stuck with a resolved promise.
- All state is encapsulated, so you don't have to worry about scope issues with the resolve/reject functions.
内容的提问来源于stack exchange,提问作者Amrmsmb
相关产品推荐
相关产品推荐

