Skip to content

Commit 21fce02

Browse files
committed
Add async mutex
1 parent b9180b3 commit 21fce02

1 file changed

Lines changed: 60 additions & 0 deletions

File tree

JavaScript/0-async.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
'use strict';
2+
3+
class AsyncMutex {
4+
#queue = [];
5+
#held = false;
6+
7+
enter() {
8+
if (!this.#held) {
9+
this.#held = true;
10+
return Promise.resolve();
11+
}
12+
return new Promise((resolve) => {
13+
this.#queue.push(resolve);
14+
});
15+
}
16+
17+
leave() {
18+
const next = this.#queue.shift();
19+
if (next) return void queueMicrotask(next);
20+
this.#held = false;
21+
}
22+
}
23+
24+
class Account {
25+
#mutex = new AsyncMutex();
26+
#balance = 0;
27+
28+
get balance() {
29+
return this.#balance;
30+
}
31+
32+
async deposit(amount, workTime) {
33+
await this.#mutex.enter();
34+
try {
35+
const before = this.#balance;
36+
await delay(workTime);
37+
this.#balance = before + amount;
38+
return this.#balance;
39+
} finally {
40+
this.#mutex.leave();
41+
}
42+
}
43+
}
44+
45+
const delay = (ms) =>
46+
new Promise((resolve) => setTimeout(resolve, ms));
47+
48+
const main = async () => {
49+
const account = new Account();
50+
51+
await Promise.all([
52+
account.deposit(10, 50),
53+
account.deposit(20, 10),
54+
account.deposit(30, 5),
55+
]);
56+
57+
console.log(account.balance);
58+
};
59+
60+
main().catch(console.error);

0 commit comments

Comments
 (0)