+interface Waitable<Value> {
+ size: number;
+ values(): IterableIterator<Value>;
+ waiters: Set<(value: Value | null) => void> | null;
+}
+
+function Get<Value>(set: Waitable<Value>, code?: () => void): Promise<Value> {
+ return new Promise<Value>((resolve, reject) => {
+ if (set.size !== 0)
+ resolve(set.values().next().value);
+ else {
+ if (set.waiters === null)
+ set.waiters = new Set<(value: Value | null) => void>();
+ set.waiters.add((value: Value | null) => {
+ if (value === null)
+ reject();
+ else
+ resolve(value);
+ });
+ if (code !== undefined)
+ code();
+ }
+ });
+}
+