typescript - simple util that lets to use await multiple times and resolve them together by single call
TypeScript[Edit]
+
0
-
0
TypeScript - simple util that lets to use await multiple times and resolve them together by single call
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91type ResolveCallback<T extends unknown> = (result: T) => void; type RejectCallback = (error?: any) => void; class Locker<T extends unknown> { private _promise: Promise<T> | null = null; private _resolve: ResolveCallback<T> | null = null; private _reject: RejectCallback | null = null; private _state: 'result' | 'error' | null = null; private _value: T | any | null = null; /* * Waits if `lock()` method was called until `resolve()` or `reject()` method is called. */ public wait = async (): Promise<T> => { if (this._promise) { return await this._promise; } else { switch (this._state) { case 'result': return this._value as T; case 'error': throw this._value; default: throw new Error('Locker has unknown state.'); } } }; /* * Locks state by that may be unlocked by `resolve()` or `reject()` method call. */ public lock = (): boolean => { if (this._promise) { return false; } const executor = (resolve: ResolveCallback<T>, reject: RejectCallback): void => { this._resolve = resolve; this._reject = reject; }; this._promise = new Promise(executor); return true; }; /* * Unlocks the call to the `wait()` method and returns the result from it. */ public resolve = (result: T): void => { if (this._promise) { this._promise = null; this._state = 'result'; this._value = result; return this._resolve!(result); } else { throw new Error('Locker is not locked.'); } }; /* * Unlocks the call to the `wait()` method and throws the error from it. */ public reject = (error?: any): void => { if (this._promise) { this._promise = null; this._state = 'error'; this._value = error; return this._reject!(error); } else { throw new Error('Locker is not locked.'); } }; } // Usage example: const locker = new Locker(); const method = async (): Promise<void> => { console.log(`Method called!`); try { const result = await locker.wait(); console.log(`Method unlocked! Message: ${result}`); } catch (error) { console.error(`Method unlocked! Error: ${error}`); } }; locker.lock(); // <------------------------------------------------- blocks `locker.wait()` call method(); method(); method(); setTimeout((): void => locker.resolve('Job done!'), 1000); // <----- resolves `locker.wait()` call after 1 second