Created
May 17, 2025 20:08
-
-
Save hartwork/0b5ac677ccde856e89f8e13e5ccf6e19 to your computer and use it in GitHub Desktop.
Wait for callbacks to finish and access their results in TypeScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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