Skip to content

Instantly share code, notes, and snippets.

@b2whats
Last active April 23, 2025 15:35
Show Gist options
  • Save b2whats/fa2cda39a5e7ee402c2af5bb82367f3b to your computer and use it in GitHub Desktop.
Save b2whats/fa2cda39a5e7ee402c2af5bb82367f3b to your computer and use it in GitHub Desktop.
class AsyncBarrier {
private open = true;
private barrier = Promise.resolve();
private resolver = () => {};
public events = new Set<string>();
private resolvedEvents = new Set<string>();
constructor(...events: string[]) {
if (events.length === 0) return;
this.barrier = this.createBarrier();
this.events = new Set(events);
}
private createBarrier(): Promise<void> {
return new Promise((done) => {
this.resolver = done;
this.open = false;
});
}
add(...names: string[]) {
names.forEach((name) => {
if (this.events.has(name)) return;
this.events.add(name);
this.open && this.createBarrier();
});
}
resolve(name: string): void {
if (this.open) return;
this.resolvedEvents.add(name);
if (this.resolvedEvents.size === this.events.size) this.resolver();
}
restore() {
if (this.events.size === 0) return;
this.resolvedEvents.clear();
this.barrier = this.createBarrier();
}
async wait(): Promise<void> {
if (!this.open) await this.barrier;
}
}
class AsyncBarrier {
private resolved;
private barrier;
private resolve = () => {};
constructor(resolved: boolean = false) {
this.resolved = resolved;
this.barrier = resolved ? Promise.resolve() : this.createBarrier();
}
private createBarrier(): Promise<void> {
return new Promise((done) => (this.resolve = done));
}
open() {
if (this.resolved) return;
this.resolved = true;
this.resolve();
}
close() {
if (this.resolved === false) return;
this.resolved = false;
this.barrier = this.createBarrier();
}
async wait(): Promise<void> {
if (!this.resolved) await this.barrier;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment