0


JavaScript多线程极速入门- web worker,手把手带你写代码,提高代码效率

单线程与多线程概念

单线程

定义
单线程指的是程序中只有一条执行路径,即程序按顺序一行一行地执行代码。在任何给定的时刻,只有一个任务在执行。

特点

  1. 顺序执行:程序按照代码的顺序从上到下依次执行。
  2. 简单性:由于没有并发执行的代码路径,因此编程和调试相对简单。
  3. 资源消耗少:不需要额外的线程管理开销。
  4. 执行效率低:在处理耗时操作时,整个程序会被阻塞,无法执行其他任务。

应用场景

  • 一些简单的、不需要并发处理的程序,如简单的计算器。
  • 实时性要求不高的任务。

多线程

定义
多线程指的是程序中存在多条执行路径,即可以同时执行多个任务。每个任务称为一个线程,这些线程共享程序的内存空间和系统资源。

特点

  1. 并发执行:多个线程可以同时运行,提高程序的执行效率。
  2. 资源共享:线程可以访问程序中的共享数据(需要同步机制来避免数据竞争)。
  3. 线程间通信:线程之间可以通过共享内存、消息传递等方式进行通信。
  4. 复杂性增加:编程和调试多线程程序相对复杂,需要考虑线程同步、死锁等问题。
  5. 开销增加:创建和管理线程需要一定的系统资源开销。

应用场景

  • 需要同时处理多个任务的情况,如Web服务器、多线程下载等。
  • 实时性要求高的任务,如游戏开发中的动画渲染和输入处理。
  • 复杂的计算任务,可以通过多线程实现并行计算,提高计算效率。

web worker概念

一、定义与背景

  • 定义:Web Worker是一个在浏览器后台线程中运行的JavaScript脚本,它独立于主线程执行,可以处理耗时的计算任务而不影响页面的性能和响应速度。
  • 背景:在单线程的JavaScript环境中,长时间运行的任务会阻塞主线程,导致用户界面无响应。为了解决这个问题,Web Worker提供了一种在后台线程中运行脚本的机制,以实现并行处理。

二、工作原理

  • 创建Worker:首先,需要创建一个JavaScript文件,用于编写Web Worker的逻辑。然后,在主线程的JavaScript代码中,使用new Worker()构造函数创建一个Web Worker实例,并指定该Worker文件的路径。
  • 消息传递:主线程和Web Worker之间通过消息传递进行通信。主线程可以使用postMessage()方法向Web Worker发送消息,而Web Worker则使用相同的方法将结果发送回主线程。这种通信方式是基于事件的,即当消息到达时,会触发相应的事件处理程序。
  • 执行任务:在Web Worker的JavaScript文件中,编写需要在后台执行的任务逻辑。这可以包括耗时的计算、数据处理或其他操作。当Web Worker接收到主线程发送的消息时,它会执行相应的任务,并将结果发送回主线程。

三、特点与限制

  • 特点:1. 并行处理:Web Worker允许在后台线程中执行脚本,实现并行处理,从而提高应用程序的性能。2. 独立性:Web Worker运行在独立的线程中,无法直接访问主线程的DOM、全局变量和大多数浏览器API。这种独立性确保了Web Worker不会干扰主线程的运行。3. 消息传递:主线程和Web Worker之间通过消息传递进行通信,这种通信方式是基于事件的,具有异步性。
  • 限制:1. 无法直接操作DOM:由于Web Worker运行在独立的线程中,因此无法直接访问或修改DOM。如果需要更新页面内容,必须通过消息传递将结果发送回主线程,由主线程来更新DOM。2. 全局作用域不同:Web Worker的全局作用域是WorkerGlobalScope,而不是主线程的window对象。因此,一些在主线程中可用的全局变量和函数在Web Worker中可能不可用。3. 浏览器兼容性:虽然大多数现代浏览器都支持Web Worker,但一些较旧的浏览器(如Internet Explorer的某些版本)可能不支持或仅支持部分功能。

四、应用场景

  • 复杂计算:对于需要执行复杂计算的任务(如图像处理、视频解码、大规模数据处理等),可以使用Web Worker在后台线程中执行这些计算,从而避免阻塞主线程并提高应用程序的响应速度。
  • 耗时操作:对于耗时较长的操作(如文件读取、网络请求等),可以使用Web Worker在后台线程中执行这些操作,以便用户可以继续与页面进行交互。
  • 并行处理:在需要并行处理多个任务的情况下(如多线程下载、并发请求等),可以使用Web Worker来创建多个后台线程并同时执行任务。

web worker实战

该实战基于vue框架基础,需下载安装 worker-loader

.vue文件页面代码

使用new Worker方法创建一个worker实例方法中需要配置你的web worker的js文件的路径,我这里是@/utils/worker1.js,然后可以监听message动作(onmessage),打印出js文件的发送的message信息

<template>
  <div>

  </div>
</template>
<script>
export default {
  name: 'APP',
  data () {
    return {
    }
  },
  methods: {
    testWorker () {
      const worker1 = new Worker(new URL('@/utils/worker1.js', import.meta.url))
    
      worker1.onmessage = function (e) {
        console.log(e)
      }
    }
  },
  created () {
  },
  mounted () {
    this.testWorker()
  }
}
</script>
<style lang="less" scoped>
/* @import url(); 引入css类 */

</style>

worker1.js文件代码

使用web worker的全局对象self进行发送message动作(postMessage)

self.postMessage('进行多线程1')

打印结果

可以看到控制台打印出了messageEvent对象,其中data为发送的message,而这个动作的是web worker开辟的多线程中完成的,不是在js主线程

web worker多线程利用

知道了可以利用多线程,我们就可以将多个耗时的js代码放入不同的web worker的js文件中,使其能一起进行执行

.vue文件页面代码修改

加入了三个web worker的js文件,多线程执行文件的代码

<template>
  <div>

  </div>
</template>
<script>
// import worker1 from '@/utils/worker1.js'
export default {
  name: 'APP',
  data () {
    return {
    }
  },
  methods: {
    testWorker () {
      const worker1 = new Worker(new URL('@/utils/worker1.js', import.meta.url))
      const worker2 = new Worker(new URL('@/utils/worker2.js', import.meta.url))
      const worker3 = new Worker(new URL('@/utils/worker3.js', import.meta.url))

      worker1.onmessage = function (e) {
        console.log(e.data)
      }
      worker2.onmessage = function (e) {
        console.log(e.data)
      }
      worker3.onmessage = function (e) {
        console.log(e.data)
      }
    }
  },
  created () {
  },
  mounted () {
    this.testWorker()
  }
}
</script>
<style lang="less" scoped>
/* @import url(); 引入css类 */

</style>

创建多个js文件放入耗时的js代码

调用文件中一个耗时的函数并打印出执行时间


function fb (n) {
  if (n === 1 || n === 2) {
    return 1
  }
  return fb(n - 1) + fb(n - 2)
}
console.time('fb执行时间1')
fb(43)
console.timeEnd('fb执行时间1')
self.postMessage('进行多线程1')
//worker1.js

function fb (n) {
  if (n === 1 || n === 2) {
    return 1
  }
  return fb(n - 1) + fb(n - 2)
}
console.time('fb执行时间2')
fb(43)
console.timeEnd('fb执行时间2')
self.postMessage('进行多线程2')
//worker2.js

function fb (n) {
  if (n === 1 || n === 2) {
    return 1
  }
  return fb(n - 1) + fb(n - 2)
}
console.time('fb执行时间3')
fb(43)
console.timeEnd('fb执行时间3')
self.postMessage('进行多线程3')
//worker3.js

打印结果

可以看到三个js中的函数同时执行,差不多同一刻一起打印出来,实现了多线程的应用

希望大家能学习到,一起交流讨论


本文转载自: https://blog.csdn.net/m0_63712057/article/details/143272508
版权归原作者 爱编程的吉米 所有, 如有侵权,请联系我们删除。

“JavaScript多线程极速入门- web worker,手把手带你写代码,提高代码效率”的评论:

还没有评论