Skip to content

Commit 7f37874

Browse files
authoredNov 26, 2024··
refactor/promise (#176)
* refactor(promise): rewrite promise * refactor(promise): rewrite queue * chore: resolve conflicts
1 parent 9c49b2d commit 7f37874

File tree

3 files changed

+43
-28
lines changed

3 files changed

+43
-28
lines changed
 

‎bun.lockb

-2.69 KB
Binary file not shown.

‎package.json

+7-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
},
1717
"devDependencies": {
1818
"@commitlint/cli": "^18.6.1",
19-
"@commitlint/config-conventional": "^19.5.0",
19+
"@commitlint/config-conventional": "^19.6.0",
2020
"@semantic-release/changelog": "^6.0.3",
2121
"@semantic-release/commit-analyzer": "^11.1.0",
2222
"@semantic-release/git": "^10.0.1",
@@ -26,8 +26,8 @@
2626
"@types/lodash.isfunction": "^3.0.9",
2727
"@typescript-eslint/eslint-plugin": "^6.21.0",
2828
"@typescript-eslint/parser": "^6.21.0",
29-
"@vitest/coverage-istanbul": "^2.1.3",
30-
"bun-types": "^1.1.30",
29+
"@vitest/coverage-istanbul": "^2.1.6",
30+
"bun-types": "^1.1.37",
3131
"commitizen": "^4.3.1",
3232
"eslint": "8.57.0",
3333
"eslint-config-airbnb-typescript": "^17.1.0",
@@ -38,13 +38,13 @@
3838
"git-cz": "^4.9.0",
3939
"husky": "^8.0.3",
4040
"lint-staged": "^15.2.10",
41-
"prettier": "^3.3.3",
41+
"prettier": "^3.4.1",
4242
"rimraf": "^5.0.10",
43-
"semantic-release": "^24.1.2",
44-
"type-fest": "^4.26.1",
43+
"semantic-release": "^24.2.0",
44+
"type-fest": "^4.28.1",
4545
"typescript": "^5.0.0",
4646
"vite-tsconfig-paths": "^4.3.2",
47-
"vitest": "^2.1.3"
47+
"vitest": "^2.1.6"
4848
},
4949
"peerDependencies": {
5050
"typescript": "^5.0.0"

‎src/data-structures/promise/index.ts

+36-21
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,21 @@ type PromiseSettledResult<T> =
6666
| PromiseFulfilledResult<T>
6767
| PromiseRejectedResult;
6868

69+
type QueueTask = {
70+
fulfilled: () => void;
71+
rejected: () => void;
72+
};
73+
6974
export class MyPromise<T = any> implements IMyPromise<T> {
7075
#state: ValueOf<typeof STATES> = STATES.PENDING;
7176

77+
#completed = false;
78+
7279
#value: T | PromiseLike<T> | undefined = undefined;
7380

7481
#reason: any = undefined;
7582

76-
#fulfilledCallbacksQueue: (() => void)[] = [];
77-
78-
#rejectedCallbacksQueue: (() => void)[] = [];
83+
#callbacksQueue: QueueTask[] = [];
7984

8085
// --- Resolve --------------------
8186
static resolve(): MyPromise<void>;
@@ -239,30 +244,24 @@ export class MyPromise<T = any> implements IMyPromise<T> {
239244

240245
// Resolve -----
241246
const internalResolve = (value: T | PromiseLike<T>) => {
242-
if (this.#state !== STATES.PENDING) return;
247+
if (this.#completed) return;
248+
this.#completed = true;
243249

244250
this.#state = STATES.FULFILLED;
245251
this.#value = value;
246252

247-
this.#fulfilledCallbacksQueue.forEach((callback) => {
248-
callback();
249-
});
250-
251-
this.#fulfilledCallbacksQueue = [];
253+
this.#executeCallbacksQueue();
252254
};
253255

254256
// Reject -----
255257
const internalReject = (reason: any) => {
256-
if (this.#state !== STATES.PENDING) return;
258+
if (this.#completed) return;
259+
this.#completed = true;
257260

258261
this.#state = STATES.REJECTED;
259262
this.#reason = reason;
260263

261-
this.#rejectedCallbacksQueue.forEach((callback) => {
262-
callback();
263-
});
264-
265-
this.#fulfilledCallbacksQueue = [];
264+
this.#executeCallbacksQueue();
266265
};
267266

268267
// Constructor execution -----
@@ -282,12 +281,9 @@ export class MyPromise<T = any> implements IMyPromise<T> {
282281
) {
283282
return new MyPromise((resolve, reject) => {
284283
if (this.#state === STATES.PENDING) {
285-
this.#fulfilledCallbacksQueue.push(() => {
286-
handleFulfilled(this.#value as T);
287-
});
288-
289-
this.#rejectedCallbacksQueue.push(() => {
290-
handleRejected(this.#reason);
284+
this.#callbacksQueue.push({
285+
fulfilled: () => handleFulfilled(this.#value as T),
286+
rejected: () => handleRejected(this.#reason),
291287
});
292288
} else if (this.#state === STATES.FULFILLED) {
293289
if (isThenable(this.#value)) {
@@ -338,6 +334,25 @@ export class MyPromise<T = any> implements IMyPromise<T> {
338334
});
339335
}
340336

337+
#executeCallbacksQueue() {
338+
let index = 0;
339+
const chain = this.#callbacksQueue;
340+
341+
while (index !== chain.length) {
342+
const { fulfilled, rejected } = chain[index];
343+
344+
if (this.#state === STATES.FULFILLED) {
345+
fulfilled();
346+
} else {
347+
rejected();
348+
}
349+
350+
index += 1;
351+
}
352+
353+
this.#callbacksQueue = [];
354+
}
355+
341356
// --- Catch --------------------
342357
catch<TResult = never>(
343358
onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null,

0 commit comments

Comments
 (0)