JS中异步和同步、并发和并行、单线程和多线程的关系

1. 单线程与多线程

单线程

  • JavaScript 是一种单线程语言,这意味着它一次只能执行一项任务。这是因为 JavaScript 的执行环境(如浏览器或 Node.js)只有一个主线程来处理代码。
  • 优点:避免了竞争条件并发问题,因为一次只有一个任务在执行。
  • 缺点:如果一个任务耗时过长,其他任务就必须等待,可能导致用户界面冻结。

多线程

  • 多线程意味着程序有多个线程可以同时执行任务。
  • JavaScript 本身是单线程的,但可以通过Web Workers(浏览器)或Worker Threads(Node.js)实现一定程度的多线程处理。

关系

  • JavaScript 核心运行环境是单线程的,但可以通过 Web Workers 等方式实现多线程。单线程一次只能执行一个任务,多线程则可以并行执行多个任务。

2. 同步与异步

同步

  • 同步代码按顺序执行,当前任务必须完成,才能开始下一个任务。同步任务会阻塞其他任务的执行。

    示例

    console.log('任务 1');
    console.log('任务 2');
    console.log('任务 3');
    

    输出顺序是 任务 1 -> 任务 2 -> 任务 3,它们是按顺序执行的。

异步

  • 异步代码允许 JavaScript 在处理某些任务时不阻塞主线程。

  • 常见的异步操作包括:

    • setTimeout/setInterval
    • 网络请求(如 fetch()
    • 文件 I/O(Node.js)

    示例

    console.log('任务 1');
    setTimeout(() => {
      console.log('异步任务');
    }, 1000);
    console.log('任务 2');
    

    输出顺序是 任务 1 -> 任务 2 -> 异步任务,异步任务会在 1 秒后执行。

关系

  • 同步任务按顺序执行,阻塞主线程,而异步任务允许在等待某个任务完成时执行其他任务,避免主线程被阻塞。

3. 并发与并行

并发

  • 并发是指即使在单线程环境中,通过异步编程,JavaScript 也可以管理多个任务。尽管这些任务不会在同一时刻同时执行,但它们可以“并发”进行。

    并发示例

    setTimeout(() => console.log('异步任务 1'), 1000);
    setTimeout(() => console.log('异步任务 2'), 500);
    console.log('同步任务');
    

    输出顺序是 同步任务 -> 异步任务 2 -> 异步任务 1。异步任务之间通过事件循环机制进行调度。

并行

  • 并行指多个任务在同一时刻同时执行,这通常需要多线程支持。JavaScript 可以通过Web Workers实现并行。

    并行示例(通过 Web Workers)

    const worker = new Worker('worker.js');
    worker.postMessage('开始计算');
    
    worker.onmessage = function(event) {
      console.log('从 worker 接收到消息:', event.data);
    };
    

关系

  • 并发是在单线程环境中通过异步任务管理多个任务,而并行是通过多线程同时执行多个任务。

4. JavaScript 的事件循环(Event Loop)

JavaScript 的事件循环机制是管理异步和并发任务的核心。它允许 JavaScript 以非阻塞的方式执行任务,尽管 JavaScript 是单线程的。

事件循环的工作流程

  1. 执行同步任务,直到任务队列为空。
  2. 检查异步任务队列,执行回调或处理已完成的异步任务。
  3. 循环执行以上步骤。

示例

console.log('任务 1');
setTimeout(() => console.log('异步任务'), 1000);
console.log('任务 2');

输出顺序:任务 1 -> 任务 2 -> 异步任务


总结关系

  • JavaScript 是单线程的,但通过异步编程和事件循环,它可以并发执行任务。
  • 同步任务会阻塞主线程,而异步任务可以在不阻塞的情况下执行。
  • JavaScript 可以通过Web Workers等方式实现多线程,实现并行处理多个任务。

深入理解异步–减少的是等待时间而不是执行时间,任务最终要放在主线程执行

  • 异步代码允许 JavaScript 在处理某些任务时不阻塞主线程。通常用于setTimeoutsetInterval、网络请求、文件操作等不会立即返回结果的任务。
  • 怎么减少的?在浏览器的配合下,异步操作可以减少等待时间:在执行异步任务(如网络请求或文件读取)时,JavaScript 发出请求后,不会等待它的完成,而是继续执行后续代码。当异步操作完成(例如定时器到期、服务器响应数据回来)时,浏览器会将其回调函数加入到任务队列,等待主线程空闲后再执行这些回调。这样,JavaScript 不会因为等待外部资源(如服务器响应)而浪费时间,确保主线程能够保持高效执行。
  • 如果将计算密集型任务设置为异步任务,由于计算任务仍然会在主线程上执行,它依然会阻塞主线程。因此,异步任务的作用并不是减少计算时间,而是避免在等待外部资源时阻塞主线程。

怎么分配任务:

  • 需要浪费时间等待的任务,例如定时器或网络请求等。建议使用 异步,它的优势在于减少等待时间,使得主线程不会因等待外部资源的响应而闲置;
  • 计算量大的任务,例如复杂的循环或递归。建议使用Web Worker,它可以在独立的线程中执行计算密集型任务,避免阻塞主线程,从而保持应用程序的流畅性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值