Skip to content

Commit e9065d8

Browse files
committed
feat(Answer-40): solution
1 parent e955435 commit e9065d8

7 files changed

Lines changed: 89 additions & 24 deletions

File tree

apps/performance/40-web-workers/project.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"apps/performance/40-web-workers/src/assets"
2121
],
2222
"styles": ["apps/performance/40-web-workers/src/styles.scss"],
23-
"scripts": []
23+
"scripts": [],
24+
"webWorkerTsConfig": "apps/performance/40-web-workers/tsconfig.worker.json"
2425
},
2526
"configurations": {
2627
"production": {

apps/performance/40-web-workers/src/app/app.component.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,33 @@
11
import { Component, inject } from '@angular/core';
2+
import { FloorPipe } from './floor.pipe';
23
import { HeavyCalculationService } from './heavy-calculation.service';
34
import { UnknownPersonComponent } from './unknown-person/unknown-person.component';
45

56
@Component({
6-
imports: [UnknownPersonComponent],
7+
imports: [UnknownPersonComponent, FloorPipe],
78
providers: [HeavyCalculationService],
89
selector: 'app-root',
910
template: `
1011
<unknown-person [step]="loadingPercentage()" class="relative grow" />
11-
<button
12-
class="my-3 w-fit self-center rounded-md border border-white px-4 py-2 text-2xl text-white"
13-
(click)="discover()">
14-
Discover
15-
</button>
16-
<div class="p-1 text-white">Progress: {{ loadingPercentage() }}%</div>
12+
13+
@if (loadingPercentage() == 0) {
14+
<button
15+
class="my-3 w-fit self-center rounded-md border border-white px-4 py-2 text-2xl text-white"
16+
(click)="discover()">
17+
Discover
18+
</button>
19+
}
20+
21+
<div class="p-1 text-white">
22+
Progress: {{ loadingPercentage() | floor }}%
23+
</div>
1724
`,
1825
host: {
1926
class: `flex flex-col h-screen w-screen bg-[#1f75c0]`,
2027
},
2128
})
2229
export class AppComponent {
2330
private heavyCalculationService = inject(HeavyCalculationService);
24-
2531
readonly loadingPercentage = this.heavyCalculationService.loadingPercentage;
2632

2733
discover() {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/// <reference lib="webworker" />
2+
3+
addEventListener('message', ({ data }) => {
4+
if (data === 'start') {
5+
randomHeavyCalculationFunction();
6+
}
7+
});
8+
9+
function randomHeavyCalculationFunction() {
10+
for (let num = 2; num <= 10000000; num++) {
11+
let randomFlag = true;
12+
for (let i = 2; i <= Math.sqrt(num); i++) {
13+
if (num % i === 0) {
14+
randomFlag = false;
15+
break;
16+
}
17+
}
18+
if (randomFlag) {
19+
postMessage('prime found');
20+
}
21+
}
22+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Pipe, PipeTransform } from '@angular/core';
2+
3+
@Pipe({
4+
name: 'floor',
5+
})
6+
export class FloorPipe implements PipeTransform {
7+
transform(value: number): number {
8+
return Math.floor(value);
9+
}
10+
}

apps/performance/40-web-workers/src/app/heavy-calculation.service.ts

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,23 @@ import { Injectable, computed, signal } from '@angular/core';
44
export class HeavyCalculationService {
55
private finalLength = 664579;
66
private loadingLength = signal(0);
7+
private worker: Worker | null = null;
8+
9+
constructor() {
10+
this.worker = new Worker(new URL('./app.worker', import.meta.url));
11+
this.worker.onmessage = () => {
12+
this.loadingLength.update((l) => l + 1);
13+
};
14+
}
715

816
loadingPercentage = computed(
917
() => (this.loadingLength() * 100) / this.finalLength,
1018
);
1119

1220
startLoading() {
13-
this.randomHeavyCalculationFunction();
14-
}
15-
16-
private randomHeavyCalculationFunction() {
17-
for (let num = 2; num <= 10000000; num++) {
18-
let randomFlag = true;
19-
for (let i = 2; i <= Math.sqrt(num); i++) {
20-
if (num % i === 0) {
21-
randomFlag = false;
22-
break;
23-
}
24-
}
25-
if (randomFlag) {
26-
this.loadingLength.update((l) => l + 1);
27-
}
21+
if (!this.worker) {
22+
throw new Error('Web Worker is not supported in this environment.');
2823
}
24+
this.worker.postMessage('start');
2925
}
3026
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Injectable } from '@angular/core';
2+
3+
@Injectable({
4+
providedIn: 'root',
5+
})
6+
export class WebWorkerService {
7+
private worker: Worker;
8+
9+
constructor() {
10+
this.worker = new Worker(new URL('./worker', import.meta.url));
11+
}
12+
13+
executeTask(data: any): Promise<any> {
14+
return new Promise((resolve, reject) => {
15+
this.worker.postMessage(data);
16+
this.worker.onmessage = ({ data }) => {
17+
resolve(data);
18+
};
19+
});
20+
}
21+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": "../../../tsconfig.base.json",
3+
"compilerOptions": {
4+
"outDir": "../../..//out-tsc/worker",
5+
"lib": ["es2018", "webworker"],
6+
"types": []
7+
},
8+
"include": ["src/**/*.worker.ts"]
9+
}

0 commit comments

Comments
 (0)