本文档描述了如何使用 Web Worker 和 Promise 实现多任务的异步执行。
Web Worker 实现多任务的异步执行
1. 概述
本部分描述了如何使用 Web Worker 实现多任务的异步执行。通过将任务分配给多个 Web Worker,可以有效地利用多核 CPU 提升任务处理效率,并保持主线程的响应性。
2. 代码结构
work.js: 定义了每个 Web Worker 的逻辑,用于处理分配给它的子任务。
main.ts: 主线程代码,负责创建和管理多个 Web Worker,并向它们发送任务数据。
3. 详细步骤
3.1 创建 Web Worker
在 main.ts
中,我们首先定义了一个 workers
数组来存储所有的 Web Worker 实例,并设置了 workerCount
变量来跟踪剩余的 Worker 数量。
const workers: Worker[] = [];
let workerCount = 10; // Worker 的数量
3.2 初始化计时
记录开始时间,以便后续计算总耗时。
const startTime = Date.now();
3.3 创建并启动 Web Worker
使用 for
循环创建指定数量的 Web Worker,并为每个 Worker 设置消息接收和错误处理事件监听器。
for (let i = 0; i < workerCount; i++) {
const worker = new Worker(new URL('./worker.js', import.meta.url), { type: 'module' });
workers.push(worker);
// 监听 Worker 发送的消息
worker.onmessage = function(event) {
console.log('从 Worker 收到的消息:', event.data);
workerCount--;
if (workerCount === 0) {
console.log('所有 Worker 已经完成任务。');
const endTime = Date.now();
console.log(`总耗时: ${endTime - startTime} 毫秒`);
workers.forEach(worker => worker.terminate());
}
};
// 监听 Worker 错误
worker.onerror = function(error) {
console.error('Worker 错误:', error);
workerCount--;
if (workerCount === 0) {
console.log('所有 Worker 已经完成任务。');
const endTime = Date.now();
console.log(`总耗时: ${endTime - startTime} 毫秒`);
workers.forEach(worker => worker.terminate());
}
};
// 发送数据给 Web Worker
worker.postMessage({
data: `Hello, Worker!`,
index: i,
});
}
3.4 Web Worker 处理逻辑
在 work.js
中,每个 Web Worker 接收到主线程发送的数据后,会模拟一个耗时任务(使用 setTimeout
),并在任务完成后向主线程发送消息。
self.onmessage = function(event) {
const { data, index } = event.data;
const start = Date.now();
console.log('接受到数据', data);
console.log('开始执行子任务', index);
setTimeout(() => {
console.log(`子任务${index}结束,耗时:`, Date.now() - start);
self.postMessage({ data });
}, index * 500);
};
4. 运行结果
每个 Web Worker 在接收到任务后会立即开始执行,并在指定的时间间隔后完成任务。
主线程会在所有 Web Worker 完成任务后输出总耗时,并终止所有 Web Worker。
5. 注意事项
确保
worker.js
和main.ts
文件路径正确。Web Worker 的数量可以根据实际需求进行调整。
在生产环境中,建议对 Web Worker 的通信和错误处理进行更详细的日志记录和异常处理。
Promise 实现多任务的异步执行
1 概述
本部分介绍了如何使用 Promise 实现多任务的异步执行。通过 Promise,我们可以更方便地处理多个异步任务,并在所有任务完成后执行特定的操作。
2 代码结构
main.ts: 主线程代码,负责创建和管理多个 Promise,并处理它们的结果。
3 详细步骤
3.1 创建多个 Promise
在 main.ts
中,我们首先创建一个包含多个 Promise 的数组,每个 Promise 模拟一个耗时任务。
const tasks = [];
let taskCount = 10; // 任务的数量
const startTime = Date.now();
for (let i = 0; i < taskCount; i++) {
const task = new Promise((resolve, reject) => {
setTimeout(() => {
console.log(`任务${i}结束,耗时:`, Date.now() - startTime);
resolve(`任务${i}完成`);
}, i * 500);
});
tasks.push(task);
}
3.2 使用 Promise.all
处理所有 Promise
使用 Promise.all
方法可以等待所有 Promise 完成,并在所有任务完成后执行特定的操作。
Promise.all(tasks)
.then(results => {
console.log('所有任务已经完成。');
console.log('任务结果:', results);
const endTime = Date.now();
console.log(`总耗时: ${endTime - startTime} 毫秒`);
})
.catch(error => {
console.error('任务错误:', error);
});
4 运行结果
每个 Promise 在接收到任务后会立即开始执行,并在指定的时间间隔后完成任务。
主线程会在所有 Promise 完成任务后输出总耗时,并显示所有任务的结果。
5 注意事项
确保每个 Promise 的逻辑正确,并且能够正确地 resolve 或 reject。
在生产环境中,建议对 Promise 的错误处理进行更详细的日志记录和异常处理。
总结
Web Worker 实现多任务异步执行的优势
多线程处理: Web Worker 可以在独立的线程中执行任务,不会阻塞主线程,适合处理耗时的计算密集型任务。
资源隔离: 每个 Web Worker 都有自己的全局作用域,避免了主线程和 Worker 之间的变量冲突。
更好的性能: 通过利用多核 CPU,可以显著提高任务处理效率。
Promise 实现多任务异步执行的优势
简洁的语法: 使用 Promise 可以更简洁地处理多个异步任务,避免了回调地狱。
更好的可读性: Promise 的链式调用使得代码更易读和维护。
错误处理: Promise 提供了更方便的错误处理机制,可以通过
.catch
方法统一处理错误。
选择合适的方案
Web Worker: 适用于需要在独立线程中执行的耗时任务,特别是计算密集型任务。
Promise: 适用于需要在主线程中处理的异步任务,特别是 I/O 操作或其他非阻塞任务。
通过合理选择和结合使用 Web Worker 和 Promise,可以更好地利用 JavaScript 的异步特性,提高应用程序的性能和响应速度。