akun
akun
发布于 2025-03-21 / 0 阅读
0
0

多任务异步执行

本文档描述了如何使用 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.jsmain.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 的异步特性,提高应用程序的性能和响应速度。


评论