Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e3480bb

Browse files
authored
Merge pull request #10 from devmargooo/promise-race
Promise.race example
2 parents 62f67db + bad1f52 commit e3480bb

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Javascript Memory Leaks Page
1212
* [Closures](./docs/Closures/README.md)
1313
* [Not used code](./docs/Closures/NotUsedCode.md)
1414
* [MeteorJS Example](./docs/Closures/MeteorJSExample.md)
15+
* [Promise.race Example](./docs/Closures/Promise.race.md)
1516
* [DOM References](./docs/DOMReferences/README.md)
1617
* [Simple static memory leak](./docs/DOMReferences/SimpleStaticMemoryLeak.md)
1718
* [jQuery](./docs/JQuery/README.md)

docs/Closures/Promise.race.md

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
## Not used code
2+
3+
[Details](https://github.com/nodejs/node/issues/17469#issuecomment-685216777)
4+
5+
When you call Promise.race with a long-running promise, the resolved value of the returned promise gets retained for as long as each of its promises do not settle.
6+
Example code to demonstrate:
7+
8+
```js
9+
async function randomString(length) {
10+
await new Promise((resolve) => setTimeout(resolve, 1));
11+
let result = "";
12+
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
13+
for (let i = 0; i < length; i++) {
14+
result += characters.charAt(Math.floor(Math.random() * characters.length));
15+
}
16+
return result;
17+
}
18+
19+
(async function main() {
20+
let i = 0;
21+
const pending = new Promise(() => {});
22+
while (true) {
23+
await Promise.race([pending, randomString(10000)]);
24+
if (i++ % 1000 === 0) {
25+
const usage = process.memoryUsage();
26+
const rss = Math.round(usage.rss / (1024 ** 2) * 100) / 100;
27+
const heapUsed = Math.round(usage.heapUsed / (1024 ** 2) * 100) / 100;
28+
console.log(`RSS: ${rss} MiB, Heap Used: ${heapUsed} MiB`);
29+
}
30+
}
31+
})();
32+
```
33+
In this example, we pass a large random string along with a non-settling promise to Promise.race, and the result is that every single one of these strings is retained.
34+
35+
**How to fix:**
36+
Avoid Promise.race. Replacing your "await Promise.race" expressions with "await new Promise" expressions, where the newly constructed Promise sets a function variable in the outer scope.
37+
38+
```js
39+
(async function main() {
40+
let i = 0;
41+
// These functions are set in a promise constructor later
42+
let resolve;
43+
let reject;
44+
45+
const pending = new Promise(() => {});
46+
pending.then((value) => resolve(value), (err) => reject(err));
47+
48+
while (true) {
49+
randomString(10000).then((value) => resolve(value), (err) => reject(err));
50+
// This is the await call which replaces the `await Promise.race` expression in the leaking example.
51+
// It sets callbacks for our promises
52+
await new Promise((resolve1, reject1) => {
53+
resolve = resolve1;
54+
reject = reject1;
55+
});
56+
if (i++ % 1000 === 0) {
57+
const usage = process.memoryUsage();
58+
const rss = Math.round(usage.rss / (1024 ** 2) * 100) / 100;
59+
const heapUsed = Math.round(usage.heapUsed / (1024 ** 2) * 100) / 100;
60+
console.log(`RSS: ${rss} MiB, Heap Used: ${heapUsed} MiB`);
61+
}
62+
}
63+
})();
64+
```

docs/Closures/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22

33
* [Not used code](./NotUsedCode.md)
44
* [MeteorJS Example](./MeteorJSExample.md)
5+
* [Promise.race Example](./Promise.race.md)

0 commit comments

Comments
 (0)