Skip to content

Commit 2f8da6f

Browse files
committed
update
1 parent 39da678 commit 2f8da6f

File tree

3 files changed

+101
-89
lines changed

3 files changed

+101
-89
lines changed
Lines changed: 98 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,73 @@
11
<!DOCTYPE html>
22
<html lang="en">
3-
<head>
3+
4+
<head>
45
<meta charset="UTF-8" />
56
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
67
<title>Web Worker应用场景-阶乘求和计算</title>
78
<style>
8-
h1 {
9-
text-align: center;
10-
}
11-
.box {
12-
box-sizing: border-box;
13-
margin: 50px auto;
14-
padding: 50px;
15-
width: 680px;
16-
font-size: 22px;
17-
border-radius: 10px;
18-
border: 1px solid #ccc;
19-
20-
input,
21-
button {
22-
font-size: 18px;
9+
h1 {
10+
text-align: center;
2311
}
2412

25-
p {
26-
font-size: 18px;
27-
&#result {
28-
color: red;
29-
}
30-
&#takeTime {
31-
color: blue;
32-
}
13+
.box {
14+
box-sizing: border-box;
15+
margin: 50px auto;
16+
padding: 50px;
17+
width: 680px;
18+
font-size: 22px;
19+
border-radius: 10px;
20+
border: 1px solid #ccc;
21+
22+
input,
23+
button {
24+
font-size: 18px;
25+
}
26+
27+
p {
28+
font-size: 18px;
29+
30+
&#result {
31+
color: red;
32+
}
33+
34+
&#takeTime {
35+
color: blue;
36+
}
37+
}
3338
}
34-
}
3539
</style>
36-
</head>
40+
</head>
3741

38-
<body>
42+
<body>
3943
<h1>Web Worker应用场景-阶乘求和计算</h1>
4044
<hr />
4145
<div class="box">
42-
循环计算次数:
43-
<input type="number" id="num" value="2000000000" />
44-
<button id="btn">开始计算</button>
45-
<button id="btn2">停止计算</button>
46-
<p id="result"></p>
47-
<p id="takeTime"></p>
46+
循环计算次数:
47+
<input type="number" id="num" value="2000000000" />
48+
<button id="btn">开始计算</button>
49+
<button id="btn2">停止计算</button>
50+
<p id="result"></p>
51+
<p id="takeTime"></p>
4852
</div>
4953

5054
<script>
51-
// worker.js (Worker 线程代码)
52-
53-
const workerjs = `
55+
// worker.js (Worker 线程代码)
56+
const workerjs = `
5457
// 监听来自主线程的消息
58+
console.log("Worker:self对象:", self);
5559
self.onmessage = function (event) {
56-
console.log("Worker:收到计算任务 ->", event.data.loopNumber, typeof event.data.loopNumber);
60+
console.log("\\n\\n Worker:收到计算任务 ->", event.data.loopNumber, typeof event.data.loopNumber);
5761
5862
if (typeof event.data.loopNumber !== "number") {
5963
self.postMessage("对不起:loopNumber参数必须是数字!");
6064
return;
6165
}
62-
66+
6367
// 执行耗时计算
6468
let result = 0;
65-
let loop = event.data.loopNumber;
69+
// for (let i = 0; i < event.data.loopNumber; i++) { // 巨坑:经过多次测试后发现,将从主线程发送过来的参数event.data.loopNumber,直接放在for循环中,会导致循环计算的时间会大大增加(当loopNumber的值为2000000000的情况下,循环耗时90.44秒),原因:由于for循环中的参数event.data.loopNumber,在每循环一次都会重新计算,导致循环时间变长!
70+
let loop = event.data.loopNumber; // 所以:一定要将参数loopNumber,提前计算好,放在一个变量中(这样当loopNumber的值为2000000000的情况下,循环耗时2.03秒,整整少了88秒的耗时!!),循环中直接使用变量loop,从而避免每次循环都重新计算参数event.data.loopNumber,从而提高循环效率!
6671
for (let i = 0; i < loop; i++) {
6772
result += i; // 模拟一个耗时操作
6873
}
@@ -74,56 +79,60 @@ <h1>Web Worker应用场景-阶乘求和计算</h1>
7479
// 计算完成后,可以关闭自己
7580
self.close();
7681
console.log("Worker:关闭自己!");
77-
};
78-
`;
82+
};`;
83+
84+
7985

86+
// main.js (主线程代码)
87+
let worker = null;
88+
const $result = document.querySelector("#result");
89+
const $takeTime = document.querySelector("#takeTime");
90+
document.getElementById("btn").addEventListener("click", function () {
91+
let start_time = "";
92+
93+
// 创建一个新的 Worker
94+
// worker = new Worker("worker.js");
95+
// worker = new Worker(new URL('./worker.js', import.meta.url)); // 在Vue.js中加载worker.js文件
96+
// worker = new Worker(new Blob([workerjs], {type: "application/javascript"})); // 使用 Blob 对象 来创建 Worker线程,这样就不用去加载外部的worker.js文件,就可以避免 CORS 问题了!!
97+
const workerUrl = URL.createObjectURL(new Blob([workerjs], { type: "application/javascript" }))
98+
worker = new Worker(workerUrl); // 注意:由于Content Security Policy (CSP)限制导致的。现代浏览器出于安全考虑,可能会阻止通过Blob URL创建Web Worker。
99+
// 使用完毕后释放URL
100+
URL.revokeObjectURL(workerUrl);
101+
// 监听来自 Worker 的消息
102+
worker.onmessage = function (event) {
103+
// event.data 是 Worker 返回的结果
104+
console.log("\n\n主线程:收到计算结果 ->", event.data);
105+
const ms = (performance.now() - start_time).toFixed(2);
106+
107+
$takeTime.innerHTML =
108+
"耗时:" + ms + "毫秒(ms)," + (ms / 1000).toFixed(2) + "秒(s)";
109+
$result.innerHTML = "结果:" + event.data;
110+
};
80111

81-
// main.js (主线程代码)
82-
let worker = null;
83-
const $result = document.querySelector("#result");
84-
const $takeTime = document.querySelector("#takeTime");
85-
document.getElementById("btn").addEventListener("click", function () {
86-
let start_time = "";
87-
88-
// 创建一个新的 Worker
89-
// worker = new Worker("worker.js");
90-
// worker = new Worker(new URL('./worker.js', import.meta.url)); // 在Vue.js中加载worker.js文件
91-
// worker = new Worker(new Blob([workerjs], {type: "application/javascript"})); // 使用 Blob 对象 来创建 Worker线程,这样就不用去加载外部的worker.js文件,就可以避免 CORS 问题了!!
92-
worker = new Worker(URL.createObjectURL(new Blob([workerjs], {type: "application/javascript"}))); // 注意:由于Content Security Policy (CSP)限制导致的。现代浏览器出于安全考虑,可能会阻止通过Blob URL创建Web Worker。
93-
// 监听来自 Worker 的消息
94-
worker.onmessage = function (event) {
95-
// event.data 是 Worker 返回的结果
96-
console.log("\n\n主线程:收到计算结果 ->", event.data);
97-
const ms = (performance.now() - start_time).toFixed(2);
98-
99-
$takeTime.innerHTML =
100-
"耗时:" + ms + "毫秒(ms)," + (ms / 1000).toFixed(2) + "秒(s)";
101-
$result.innerHTML = "结果:" + event.data;
102-
};
103-
104-
// 监听错误
105-
worker.onerror = function (error) {
106-
console.error("主线程:Worker 发生错误 ->", error);
107-
$result.innerHTML = "错误:" + error.message;
108-
};
109-
110-
// 获取用户输入的数字
111-
const num = document.getElementById("num").value;
112-
113-
// 向 Worker 发送消息,开始计算
114-
console.log("主线程:开始发送计算任务...");
115-
$result.innerHTML = "Worker线程 正在计算中...";
116-
$takeTime.innerHTML = "";
117-
start_time = performance.now();
118-
worker.postMessage({ loopNumber: Number(num) });
119-
});
120-
121-
document.getElementById("btn2").addEventListener("click", function () {
122-
// 停止 Worker
123-
worker.terminate();
124-
console.log("主线程:停止计算...");
125-
$result.innerHTML = "已停止计算...";
126-
});
112+
// 监听错误
113+
worker.onerror = function (error) {
114+
console.error("主线程:Worker 发生错误 ->", error);
115+
$result.innerHTML = "错误:" + error.message;
116+
};
117+
118+
// 获取用户输入的数字
119+
const num = document.getElementById("num").value;
120+
121+
// 向 Worker 发送消息,开始计算
122+
console.log("主线程:开始发送计算任务...");
123+
$result.innerHTML = "Worker线程 正在计算中...";
124+
$takeTime.innerHTML = "";
125+
start_time = performance.now();
126+
worker.postMessage({ loopNumber: Number(num) });
127+
});
128+
129+
document.getElementById("btn2").addEventListener("click", function () {
130+
// 停止 Worker
131+
worker.terminate();
132+
console.log("主线程:停止计算...");
133+
$result.innerHTML = "已停止计算...";
134+
});
127135
</script>
128-
</body>
129-
</html>
136+
</body>
137+
138+
</html>

Web-API/Worker-JS多线程运行环境/Web Worker/worker.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ self.onmessage = function (event) {
77
self.postMessage("对不起:loopNumber参数必须是数字!");
88
return;
99
}
10+
1011
// 执行耗时计算
1112
let result = 0;
1213
// for (let i = 0; i < event.data.loopNumber; i++) { // 巨坑:经过多次测试后发现,将从主线程发送过来的参数event.data.loopNumber,直接放在for循环中,会导致循环计算的时间会大大增加(当loopNumber的值为2000000000的情况下,循环耗时90.44秒),原因:由于for循环中的参数event.data.loopNumber,在每循环一次都会重新计算,导致循环时间变长!

Web-API/Worker-JS多线程运行环境/Web Worker/使用Blob加载workerJs文件.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ <h3>
2929
});
3030
const workerUrl = URL.createObjectURL(blob);
3131
const worker = new Worker(workerUrl);
32+
// 释放URL对象
33+
URL.revokeObjectURL(workerUrl);
3234

3335
// Worker创建成功,监听Worker返回消息
3436
worker.onmessage = function (e) {

0 commit comments

Comments
 (0)