Created
October 26, 2022 18:15
-
-
Save isthatcentered/30e41afadb5df2ca6d0245b3b901fd33 to your computer and use it in GitHub Desktop.
Typescript queue
This file contains 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
describe(`Queue`, () => { | |
describe(`isEmpty`, () => { | |
test(`Empty queue returns true`, async () => { | |
const queue = new InMemoryQueue<string>(); | |
const result = await queue.isEmpty(); | |
expect(result).toEqual(true); | |
}); | |
test(`Non empty queue returns false`, async () => { | |
const queue = new InMemoryQueue<string>(); | |
queue.offer('some_value'); | |
const result = await queue.isEmpty(); | |
expect(result).toEqual(false); | |
}); | |
}); | |
describe(`take`, () => { | |
test(`Element already queued succeeds immediately`, async () => { | |
const value = 'some_value'; | |
const queue = new InMemoryQueue<string>(); | |
queue.offer(value); | |
const result = await queue.take(); | |
expect(result).toEqual(value); | |
}); | |
test(`No element queued waits until one is offered`, async () => { | |
const value = 'some_value'; | |
const queue = new InMemoryQueue<string>(); | |
const promise = queue.take(); | |
await queue.offer(value); | |
expect(await promise).toEqual(value); | |
}); | |
test(`Multiple pending takers each receive a different element`, async () => { | |
const queue = new InMemoryQueue<string>(); | |
const promise = Promise.all([queue.take(), queue.take()]); | |
await queue.offer('A'); | |
await queue.offer('B'); | |
const [a, b] = await promise; | |
expect(a).toBe('A'); | |
expect(b).toBe('B'); | |
}); | |
}); | |
}) |
This file contains 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
export interface ReadonlyQueue<A> { | |
take(): Promise<A | undefined>; | |
isEmpty(): Promise<boolean>; | |
} | |
export interface Queue<A> extends ReadonlyQueue<A> { | |
offer(value: A): Promise<void>; | |
} | |
export class InMemoryQueue<A> implements Queue<A> { | |
private elements: A[]; | |
private takers: Array<(a: A) => void> = []; | |
constructor(elements: A[] = []) { | |
this.elements = elements; | |
} | |
async offer(value: A): Promise<void> { | |
const taker = this.takers.shift(); | |
if (!taker) { | |
this.elements.push(value); | |
return; | |
} | |
taker(value); | |
} | |
/** | |
* Returns immeiately if an item is present in queue, | |
* waits for an element to be offered otherwise | |
*/ | |
async take(): Promise<A | undefined> { | |
const element = this.elements.shift(); | |
if (element) return element; | |
return new Promise((res) => this.takers.push(res)); | |
} | |
async isEmpty(): Promise<boolean> { | |
return !this.elements.length; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment