Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { Resolver, defer } from './defer'
- export type Enqueue<T> = (value: T) => void
- export type Dequeue<T> = () => Promise<T>
- /**
- * An asynchronous queue that allows values to be
- * asynchronously pulled from the queue. Returns
- * a [enqueue, dequeue] tuple queuing and de-queuing
- * values.
- */
- export function queue<T>(): [Enqueue<T>, Dequeue<T>] {
- const promises: Promise<T>[] = []
- const awaiters: Resolver<T>[] = []
- function dequeue(): Promise<T> {
- // If we have a promise, it means that
- // the sender has enqueued a value and
- // its available immediately. Shift the
- // promise immediately
- if(promises.length > 0) {
- return promises.shift()!
- }
- // If there are no promises available,
- // create a deferred and push an awaiter.
- // Return promise to caller.
- else {
- const [promise, awaiter] = defer<T>()
- awaiters.push(awaiter)
- return promise
- }
- }
- function enqueue(item: T) {
- // If there is an awaiter, it means we have
- // a receiver awaiting on a value. Shift
- // the awaiter and resolve immediately.
- if(awaiters.length > 0) {
- const awaiter = awaiters.shift()!
- awaiter(item)
- }
- // If there is no awaiters, it means that
- // there is no receiver trying to receive
- // at this time. create a deferred and push
- // the promise for the 'next' receiver to
- // receive. Resolve awaiter immediately
- else {
- const [promise, awaiter] = defer<T>()
- awaiter(item)
- promises.push(promise)
- }
- }
- return [
- value => enqueue(value),
- () => dequeue()
- ]
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement