Pre-Initialization Queues
Learn how to use queues and the Command pattern to delay operations until the asynchronous initialization process is complete.
We'll cover the following...
Another recipe to make sure that the services of a component are invoked only after the component is initialized involves the use of queues and the Command pattern. The idea is to queue the method invocations (only those requiring the component to be initialized) received while the component isn’t yet initialized, and then execute them as soon as all the initialization steps have been completed.
Let’s see how this technique can be applied to our sample db
component.
Press + to interact
import { EventEmitter } from 'events'class DB extends EventEmitter {connected = falsecommandsQueue = []async query (queryString) {if (!this.connected) {console.log(`Request queued: ${queryString}`)return new Promise((resolve, reject) => { //(1)const command = () => {this.query(queryString).then(resolve, reject)}this.commandsQueue.push(command)})}console.log(`Query executed: ${queryString}`)}connect () {// simulate the delay of the connectionsetTimeout(() => {this.connected = truethis.emit('connected')this.commandsQueue.forEach(command => command()) //(2)this.commandsQueue = []}, 500)}}export const db = new DB()
As we already mentioned, the technique described here consists of two parts:
- If the component hasn’t been initialized—which, in our case, is when the
connected
property isfalse
—we create a command from the parameters received with the current invocation and push it to thecommandsQueue
array. When the command is executed, it’ll run the originalquery()
method again and forward the result to thePromise
we’re returning to the caller. - When the initialization of the component is completed—which, in our case, means that the connection with the