Last active
January 18, 2023 00:31
-
-
Save Drarig29/45f1c8d0d86fc1b5bfbf1aabb70b332d to your computer and use it in GitHub Desktop.
An IIFE which enqueues a promise in a single promise. Ensures promises are executed in the good order
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
/** | |
* Delays a `console.log()` for the given time amount. | |
* | |
* @param message A message to log. | |
* @param duration A delay in seconds. | |
*/ | |
function delay(message: string, duration: number): Promise<void> { | |
return new Promise((resolve) => { | |
setTimeout(() => { | |
console.log(message); | |
resolve(); | |
}, timeAmount * 1000); | |
}); | |
} | |
/** | |
* An IIFE which enqueues a promise in a single promise. Ensures promises are executed in the good order. | |
* | |
* @param promise A promise to enqueue. | |
*/ | |
const enqueuePromise = (() => { | |
let queue: Promise<any> | null = null; | |
return async (promise?: () => any) => { | |
if (!promise) return queue; | |
queue = queue ? queue.then(promise) : promise(); | |
return queue = queue && queue.then(() => queue = null); | |
}; | |
})(); | |
// Useless, but works. | |
enqueuePromise(); | |
// Enqueue two promises. | |
enqueuePromise(() => delay('promise 1', 3)); | |
enqueuePromise(() => delay('promise 2', 1)); | |
async function awaitExample() { | |
// Await for any promise enqueued in the past. | |
await enqueuePromise(); | |
// Enqueue two promises. | |
enqueuePromise(() => delay('promise 3', 3)); | |
enqueuePromise(() => delay('promise 4', 1)); | |
// Await for both promises to end. | |
await enqueuePromise(); | |
console.log('All promises done.'); | |
} | |
awaitExample(); |
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
/** | |
* Delays a `console.log()` for the given time amount. | |
* | |
* @param message A message to log. | |
* @param timeAmount A delay in seconds. | |
*/ | |
function delay(message: string, timeAmount: number): Promise<void> { | |
return new Promise((resolve) => { | |
setTimeout(() => { | |
console.log(message); | |
resolve(); | |
}, timeAmount * 1000); | |
}); | |
} | |
/** | |
* A lambda expression. | |
*/ | |
type Lambda = () => any; | |
/** | |
* A queue id. | |
*/ | |
type QueueId = string | number; | |
/** | |
* A queue. | |
*/ | |
type Queue = (promise?: Lambda) => Promise<any>; | |
/** | |
* Returns a queue which joins a promise in a single promise. Ensures promises are executed in the good order. | |
*/ | |
function makePromiseQueue(): Queue { | |
return (() => { | |
let queue: Promise<any> | null = null; | |
return async (promise?: Lambda) => { | |
if (!promise) return queue; | |
queue = queue ? queue.then(promise) : promise(); | |
return queue = queue && queue.then(() => queue = null); | |
}; | |
})(); | |
} | |
/** | |
* Enqueues a promise in the queue. | |
*/ | |
const enqueuePromise = makePromiseQueue(); | |
/** | |
* Enqueues a promise in the queue which has the given ID. | |
*/ | |
const enqueuePromiseWithId = (() => { | |
const queues: {[id in QueueId]: Queue} = {}; | |
return (id: QueueId) => queues[id] = queues[id] || makePromiseQueue(); | |
})(); | |
// Useless, but just to show that it works. | |
enqueuePromise(); | |
// Enqueue two promises. | |
enqueuePromise(() => delay('promise 1', 3)); | |
enqueuePromise(() => delay('promise 2', 1)); | |
async function awaitExample() { | |
// Await for any promise enqueued in the past. | |
await enqueuePromise(); | |
// Enqueue two promises. | |
enqueuePromise(() => delay('promise 3', 3)); | |
enqueuePromise(() => delay('promise 4', 1)); | |
// Await for both promises to end. | |
await enqueuePromise(); | |
console.log('awaitExample() done.'); | |
} | |
async function awaitWithIdExample() { | |
// Enqueue two promises in the first queue (created during the first call). | |
enqueuePromiseWithId('queue1')(() => delay('promise A (queue1)', 1)); | |
enqueuePromiseWithId('queue1')(() => delay('promise B (queue1)', 0)); | |
// Enqueue two promises in the second queue (created during the first call). | |
enqueuePromiseWithId('queue2')(() => delay('promise A (queue2)', 1)); | |
enqueuePromiseWithId('queue2')(() => delay('promise B (queue2)', 0)); | |
// Enqueue two promises in the third queue (created during the first call). | |
enqueuePromiseWithId('queue3')(() => delay('promise A (queue3)', 6)); | |
enqueuePromiseWithId('queue3')(() => delay('promise B (queue3)', 4)); | |
await enqueuePromiseWithId('queue3')(); | |
console.log('awaitWithIdExample() done.'); | |
} | |
awaitExample(); | |
awaitWithIdExample(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You can see it in the following TS Playground 😁