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信息

  1. <template>
  2. <div>
  3. </div>
  4. </template>
  5. <script>
  6. export default {
  7. name: 'APP',
  8. data () {
  9. return {
  10. }
  11. },
  12. methods: {
  13. testWorker () {
  14. const worker1 = new Worker(new URL('@/utils/worker1.js', import.meta.url))
  15. worker1.onmessage = function (e) {
  16. console.log(e)
  17. }
  18. }
  19. },
  20. created () {
  21. },
  22. mounted () {
  23. this.testWorker()
  24. }
  25. }
  26. </script>
  27. <style lang="less" scoped>
  28. /* @import url(); 引入css类 */
  29. </style>

worker1.js文件代码

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

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

打印结果

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

web worker多线程利用

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

.vue文件页面代码修改

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

  1. <template>
  2. <div>
  3. </div>
  4. </template>
  5. <script>
  6. // import worker1 from '@/utils/worker1.js'
  7. export default {
  8. name: 'APP',
  9. data () {
  10. return {
  11. }
  12. },
  13. methods: {
  14. testWorker () {
  15. const worker1 = new Worker(new URL('@/utils/worker1.js', import.meta.url))
  16. const worker2 = new Worker(new URL('@/utils/worker2.js', import.meta.url))
  17. const worker3 = new Worker(new URL('@/utils/worker3.js', import.meta.url))
  18. worker1.onmessage = function (e) {
  19. console.log(e.data)
  20. }
  21. worker2.onmessage = function (e) {
  22. console.log(e.data)
  23. }
  24. worker3.onmessage = function (e) {
  25. console.log(e.data)
  26. }
  27. }
  28. },
  29. created () {
  30. },
  31. mounted () {
  32. this.testWorker()
  33. }
  34. }
  35. </script>
  36. <style lang="less" scoped>
  37. /* @import url(); 引入css类 */
  38. </style>

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

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

  1. function fb (n) {
  2. if (n === 1 || n === 2) {
  3. return 1
  4. }
  5. return fb(n - 1) + fb(n - 2)
  6. }
  7. console.time('fb执行时间1')
  8. fb(43)
  9. console.timeEnd('fb执行时间1')
  10. self.postMessage('进行多线程1')
  11. //worker1.js
  12. function fb (n) {
  13. if (n === 1 || n === 2) {
  14. return 1
  15. }
  16. return fb(n - 1) + fb(n - 2)
  17. }
  18. console.time('fb执行时间2')
  19. fb(43)
  20. console.timeEnd('fb执行时间2')
  21. self.postMessage('进行多线程2')
  22. //worker2.js
  23. function fb (n) {
  24. if (n === 1 || n === 2) {
  25. return 1
  26. }
  27. return fb(n - 1) + fb(n - 2)
  28. }
  29. console.time('fb执行时间3')
  30. fb(43)
  31. console.timeEnd('fb执行时间3')
  32. self.postMessage('进行多线程3')
  33. //worker3.js

打印结果

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

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


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

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

还没有评论