So here's an oxymoron: I want to create an asynchronous blocking queue in javascript/typescript (if you can implement it without typescript, that's fine). Basically I want to implement something like Java's BlockingQueue
expect instead of it actually being blocking, it would be async and I can await dequeues.
Here's the interface I want to implement:
interface AsyncBlockingQueue<T> {
enqueue(t: T): void;
dequeue(): Promise<T>;
}
And I'd use it like so:
// enqueue stuff somewhere else
async function useBlockingQueue() {
// as soon as something is enqueued, the promise will be resolved:
const value = await asyncBlockingQueue.dequeue();
// this will cause it to await for a second value
const secondValue = await asyncBlockingQueue.dequeue();
}
Any ideas?
This is simply @Bergi's answer but with typescript + generics with some modifications to make it work with strict mode for my typing brothers/sisters out there.
It's quite simple actually,
dequeue
will create a promise thatenqueue
will resolve. We just have to keep the resolvers in a queue - and also care about the case where values are enqueued before they are dequeued, keeping the already fulfilled promises in a queue.I don't know TypeScript, but presumably it's simple to add the the necessary type annotations.
For better performance, use a Queue implementation with circular buffers instead of plain arrays, e.g. this one. You might also use only a single queue and remember whether you currently store promises or resolvers.