Skip to content

Instantly share code, notes, and snippets.

@hartwork
Created May 17, 2025 20:08
Show Gist options
  • Save hartwork/0b5ac677ccde856e89f8e13e5ccf6e19 to your computer and use it in GitHub Desktop.
Save hartwork/0b5ac677ccde856e89f8e13e5ccf6e19 to your computer and use it in GitHub Desktop.
Wait for callbacks to finish and access their results in TypeScript
#! /usr/bin/env node
// Copyright (c) 2025 Sebastian Pipping <[email protected]>
// SPDX-License-Identifier: 0BSD
import { Sema } from "async-sema";
// eslint-disable-next-line @typescript-eslint/no-require-imports
import assert = require("node:assert");
class ResultPipe<T> {
private sema: Sema;
private results: T[];
public constructor(count: number) {
this.sema = new Sema(count);
this.results = new Array<T>();
for (let i = 0; i < count; i++) {
this.sema.acquire();
}
}
public push(result: T): void {
this.results.push(result);
this.sema.release();
}
public async pop(): Promise<T> {
await this.sema.acquire();
const result = this.results.shift();
assert(result !== undefined); // because of how .push works above
return result;
}
}
async function asyncMain() {
const p = new ResultPipe<number>(2);
console.log("Before callback");
setTimeout(function () {
console.log("Inside callback A");
p.push(11);
}, 2000);
setTimeout(function () {
console.log("Inside callback B");
p.push(22);
}, 1000);
console.log("Waiting for callbacks to finish...");
const firstResult = await p.pop();
const secondResult = await p.pop();
console.log(
`After both callbacks, got ${firstResult} first and then ${secondResult}.`,
);
}
asyncMain();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment