ArcGIS JSAPI 学习教程 - JavaScript 子线程基础示例
·

本文主要介绍一下 JavaScript 子线程教程。
JavaScript 为单线程,因此在执行代码过程中遇到耗时操作,会导致页面卡顿。
而子线程就是为了解决这个问题,将耗时任务交给子线程去执行,主线程与子线程通信,获取任务结果,再进行后续工作即可。
需要注意的是,子线程不能操作 dom,原因为防止DOM的复杂渲染操作导致的数据冲突,具体可搜索或者 AI 一下。
本文包括 完整代码以及在线示例。
完整代码
简单设计了一个子线程示例,大概过程为,计算斐波那契数,并且利用 canvas 动态展示卡顿效果。
一种是主线程计算,主线程被占用时,canvas 小球停止移动。
而子线程计算时,主线程几乎不受影响,canvas 小球不会停止移动。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
<title>Web Worker 示例</title>
</head>
<body>
<span>计算第</span><input id="fibonacci" value="40"/><span>项斐波那契数</span>
<button onclick="startCompute()">开始计算</button>
<button onclick="startWorker()">开始计算(使用Worker)</button>
<button onclick="stopWorker()">停止Worker</button>
<div id="waiting"></div>
<div id="time"></div>
<div id="result"></div>
<canvas id="animationCanvas" width="600" height="300" style="padding-top: 5px;"> </canvas>
<script>
// 初始化动画小球
bounceBall();
let worker;
// 计算斐波那契数列(模拟耗时任务)
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
// 初始化等待HTML
function initWaitingHtml() {
document.getElementById("waiting").innerHTML = `正在计算,请稍等...`;
document.getElementById("time").innerHTML = ``;
document.getElementById("result").innerHTML = ``;
}
// 初始化结果HTML
function initResultHtml(data, timeStart) {
document.getElementById("result").innerHTML =
`斐波那契结果: ${data}`;
document.getElementById("waiting").innerHTML = ``;
document.getElementById("time").innerHTML = `计算耗时: ${performance.now() - timeStart} 毫秒`;
}
// 启动Worker
function startWorker() {
if (typeof Worker !== "undefined") {
initWaitingHtml();
worker = new Worker('./workersFolder/worker.js'); // 创建Worker
const timeStart = performance.now();
// 接收Worker结果
worker.onmessage = function (event) {
initResultHtml(event.data, timeStart);
};
// 错误处理
worker.onerror = function (error) {
console.error(`Worker错误: ${error.filename} (行: ${error.lineno})`);
};
const fibonacciNum = parseInt(document.getElementById("fibonacci").value);
// 发送计算任务(计算第40项斐波那契数)
worker.postMessage(fibonacciNum);
}
}
// 开始计算
function startCompute() {
const fibonacciNum = parseInt(document.getElementById("fibonacci").value);
initWaitingHtml();
const timeStart = performance.now();
const result = fibonacci(fibonacciNum); // 执行计算
initResultHtml(result, timeStart);
}
// 终止Worker
function stopWorker() {
if (worker) {
worker.terminate(); // 释放资源
worker = null;
console.log("Worker已终止");
}
}
// 初始化动画小球
function bounceBall() {
const canvas = document.getElementById("animationCanvas");
const ctx = canvas.getContext("2d");
// 初始化圆的属性
let x = 50; // 圆心的x坐标
let y = 160; // 圆心的y坐标
let radius = 20; // 圆的半径
let dx = 2; // x方向的速度
let dy = 1; // y方向的速度
// 绘制圆的函数
function drawCircle() {
ctx.beginPath(); // 开始一条新路径
ctx.arc(x, y, radius, 0, Math.PI * 2, false); // 绘制圆
ctx.fillStyle = 'blue'; // 设置填充颜色为蓝色
ctx.fill(); // 填充圆
// 设置边框样式
ctx.strokeStyle = 'red'; // 边框颜色
ctx.lineWidth = 3; // 边框宽度
ctx.strokeRect(0, 0, canvas.width, canvas.height);
ctx.closePath(); // 结束路径的绘制
}
// 动画函数
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除画布
drawCircle(); // 绘制圆
x += dx; // 更新x坐标
y += dy; // 更新y坐标
if (x + radius > canvas.width || x - radius < 0) { // 如果圆碰到边界,改变方向
dx = -dx; // 改变x方向的速度
}
if (y + radius > canvas.height || y - radius < 0) { // 如果圆碰到边界,改变方向
dy = -dy; // 改变y方向的速度
}
requestAnimationFrame(animate); // 递归调用animate函数,实现动画效果
}
// 开始动画
animate();
}
</script>
</body>
</html>

在线示例
ArcGIS Maps SDK for JavaScript 在线示例:JavaScript 子线程基础示例
更多推荐


所有评论(0)