Skip to content

Commit e436671

Browse files
committed
impr: add promiseWithResolvers util
makes it a bit nicer when working with promises that need to be resolved outside of the promise body !nuf
1 parent a7f4dcf commit e436671

File tree

4 files changed

+35
-21
lines changed

4 files changed

+35
-21
lines changed

frontend/src/ts/config.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
import {
1919
isDevEnvironment,
2020
isObject,
21+
promiseWithResolvers,
2122
reloadAfter,
2223
typedKeys,
2324
} from "./utils/misc";
@@ -44,8 +45,6 @@ const configLS = new LocalStorageWithSchema({
4445
},
4546
});
4647

47-
let loadDone: (value?: unknown) => void;
48-
4948
const config = {
5049
...getDefaultConfig(),
5150
};
@@ -2125,8 +2124,7 @@ export function getConfigChanges(): Partial<Config> {
21252124
return configChanges;
21262125
}
21272126

2128-
export const loadPromise = new Promise((v) => {
2129-
loadDone = v;
2130-
});
2127+
const { promise: loadPromise, resolve: loadDone } = promiseWithResolvers();
21312128

2129+
export { loadPromise };
21322130
export default config;

frontend/src/ts/modals/register-captcha.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,23 @@
11
import * as CaptchaController from "../controllers/captcha-controller";
22
import AnimatedModal from "../utils/animated-modal";
3+
import { promiseWithResolvers } from "../utils/misc";
34

4-
let resolvePromise: (token?: string) => void;
5+
let { promise, resolve } = promiseWithResolvers<string | undefined>();
56

6-
export let promise = new Promise<string | undefined>((resolve) => {
7-
resolvePromise = resolve;
8-
});
7+
export { promise };
98

109
export async function show(): Promise<void> {
1110
await modal.show({
1211
mode: "dialog",
1312
beforeAnimation: async (modal) => {
14-
promise = new Promise((resolve) => {
15-
resolvePromise = resolve;
16-
});
13+
({ promise, resolve } = promiseWithResolvers<string | undefined>());
1714
CaptchaController.reset("register");
1815

1916
CaptchaController.render(
2017
modal.querySelector(".g-recaptcha") as HTMLElement,
2118
"register",
2219
(token) => {
23-
resolvePromise(token);
20+
resolve(token);
2421
hide();
2522
}
2623
);
@@ -29,7 +26,7 @@ export async function show(): Promise<void> {
2926
}
3027

3128
function hide(resolveToUndefined = false): void {
32-
if (resolveToUndefined) resolvePromise();
29+
if (resolveToUndefined) resolve(undefined);
3330
void modal.hide();
3431
}
3532

frontend/src/ts/test/test-ui.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ export let activeWordElementOffset = 0;
197197
export let resultVisible = false;
198198
export let activeWordTop = 0;
199199
export let testRestarting = false;
200-
export let testRestartingPromise: Promise<unknown>;
201200
export let lineTransition = false;
202201
export let currentTestLine = 0;
203202
export let resultCalculating = false;
@@ -214,16 +213,18 @@ export function setActiveWordTop(val: number): void {
214213
activeWordTop = val;
215214
}
216215

217-
let restartingResolve: null | ((value?: unknown) => void);
216+
let { promise: testRestartingPromise, resolve: restartingResolve } =
217+
Misc.promiseWithResolvers();
218+
219+
export { testRestartingPromise };
220+
218221
export function setTestRestarting(val: boolean): void {
219222
testRestarting = val;
220223
if (val) {
221-
testRestartingPromise = new Promise((resolve) => {
222-
restartingResolve = resolve;
223-
});
224+
({ promise: testRestartingPromise, resolve: restartingResolve } =
225+
Misc.promiseWithResolvers());
224226
} else {
225-
if (restartingResolve) restartingResolve();
226-
restartingResolve = null;
227+
restartingResolve();
227228
}
228229
}
229230

frontend/src/ts/utils/misc.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,4 +693,22 @@ export function applyReducedMotion(animationTime: number): number {
693693
return prefersReducedMotion() ? 0 : animationTime;
694694
}
695695

696+
/**
697+
* Creates a promise with resolvers.
698+
* This is useful for creating a promise that can be resolved or rejected from outside the promise itself.
699+
*/
700+
export function promiseWithResolvers<T = void>(): {
701+
resolve: (value: T) => void;
702+
reject: (reason?: unknown) => void;
703+
promise: Promise<T>;
704+
} {
705+
let resolve!: (value: T) => void;
706+
let reject!: (reason?: unknown) => void;
707+
const promise = new Promise<T>((res, rej) => {
708+
resolve = res;
709+
reject = rej;
710+
});
711+
return { resolve, reject, promise };
712+
}
713+
696714
// DO NOT ALTER GLOBAL OBJECTSONSTRUCTOR, IT WILL BREAK RESULT HASHES

0 commit comments

Comments
 (0)