Code Review Asked by Leonel Franchelli on February 22, 2021
i’ve implemented a waiter service in Angular for syncronice multiple calls to one async function and i want to know if there exists a simplier way of atchiving the same result or if it’s over engineered
the code
import {Injectable} from '@angular/core';
export class PromiseRef {
resolve: (any?: any) => any;
reject: (any?: any) => any;
}
class ExecutionQueue {
promises = new Set<PromiseRef>();
lock: boolean = false;
constructor() {
}
hasPromises(): boolean {
return !!this.promises.size;
}
clearQueue() {
this.lock = false;
this.promises.clear();
}
add(promiseRef: PromiseRef) {
this.promises.add(promiseRef);
}
remove(promiseRef: PromiseRef) {
this.promises.delete(promiseRef);
}
}
@Injectable({providedIn: 'root'})
export class WaiterService {
private executionQueues = new Map<string, ExecutionQueue>();
constructor() {
}
isLocked(queueName: string): boolean {
return this.getQueue(queueName).lock;
}
lockQueue(queueName: string): Promise<PromiseRef> {
return new Promise<PromiseRef>(
(resolve, reject) => {
const queue = this.getQueue(queueName);
const promiseRef = new PromiseRef();
promiseRef.resolve = resolve;
promiseRef.reject = reject;
if (!queue.lock) {
queue.lock = true;
promiseRef.resolve(promiseRef);
} else {
this.addToExecutionQueue(queueName, promiseRef);
}
}
);
}
async unlockQueue(queueName: string) {
const queue = this.getQueue(queueName);
queue.lock = false;
const iterator = queue.promises.values();
const nextValue = iterator.next();
if (nextValue.done) {
return;
}
const promiseRef = nextValue.value;
queue.remove(promiseRef);
const newRef = await this.lockQueue(queueName);
promiseRef.resolve(newRef);
}
addToExecutionQueue(queueName: string, promiseRef: PromiseRef) {
const queue = this.getQueue(queueName);
queue.add(promiseRef);
}
private getQueue(queueName: string) {
let queue = this.executionQueues.get(queueName);
if (!queue) {
queue = new ExecutionQueue();
this.executionQueues.set(queueName, queue);
}
return queue;
}
}
then you should use it like this
async someFn() {
await this.waiterService.lockQueue('a_queue');
try {
// do async stuff
} finally {
this.waiterService.unlockQueue('a_queue');
}
}
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP