精华内容
下载资源
问答
  • Vue Web Worker 示例
  • vue使用web worker

    千次阅读 2019-09-28 07:12:57
    众所周知,JavaScript是单线程的,一些复杂比较耗时的操作,会阻塞页面的渲染交互,引起页面卡顿,影响用户体验。web worker是html5的新特性之一,主要就是用来解决此类... 首先,基本的web worker使用直接调用Wo...

      众所周知,JavaScript是单线程的,一些复杂比较耗时的操作,会阻塞页面的渲染交互,引起页面卡顿,影响用户体验。web worker是html5的新特性之一,主要就是用来解决此类问题,为页面额外开启一个线程,用来处理一些比较耗时操作,不影响主线程的进行。

      在实际vue项目的开发使用过程中,还是遇到不少坑,特别记录一下。

      首先,基本的web worker使用直接调用Worker构造函数,如下:

    // url: js文件路径
    // options: 配置信息
    const worker = new Worker(url, options)

      其次,不同模块间的通信主要通过postMessage进行消息推送,通过onmessage进行消息接收,如下所示:

    // a.js
    let worker = new Worker('a.js')
    worker.postMessage({
          method: 'transferLang'
    })
    worker.onmessage = function (e) {
          init(e.data.params)
    }
    // b.js
    self.onmessage = ev => {
      let funName = ev.data.method
      if (self[funName]) {
        self[funName](ev.data.params)
      } else {
        console.warn(`方法${funName}未定义`)
      }
    }
    
    self.transferLang = function () {
      let arr = []
      self.postMessage({
        params: arr
      })
    }

      在vue项目中,如果直接使用,首先遇到的问题是worker文件路径与打包解析问题,这种首先需要安装worker-loader,解析web worker,执行以下命令即可:

    npm install worker-loader -D

      vue.config.js要添加以下配置:

    configureWebpack: config => {
        config.module.rules.push({
          test: /\.worker.js$/,
          use: {
            loader: 'worker-loader',
            options: { inline: true, name: 'workerName.[hash].js' }
          }
        })
      },

      在使用的时候,就不能调用原生的Worker构造函数了,需要手动import worker文件,然后直接实例化这个文件即可,如下所示:

    // a.js
    import Worker from './b.js'
    
    let worker = new Worker()

      接着,会发现控制台会报错,“window is undefined”,这个是因为worker线程中不存在window对象,因此不能直接使用,要用this代替,要在vue.config.js中添加以下配置:

    chainWebpack: config => {
        config.output.globalObject('this')
     }

      接着在打包的时候,也会报错,需要加入以下配置,

    parallel: false

      完整的webpack配置如下:

    module.exports = {
      configureWebpack: config => {
        config.module.rules.push({
          test: /\.worker.js$/,
          use: {
            loader: 'worker-loader',
            options: { inline: true, name: 'workerName.[hash].js' }
          }
        })
      },
      parallel: false,
      chainWebpack: config => {
        config.output.globalObject('this')
      }
    }

      还存在另外一个问题,就是每次修改worker文件时,debugger调试总是保留之前的记录,感觉编译的时候存在缓存,目前解决办法是修改worker.js文件名称,比较繁琐,如果哪位大神有好的建议,不吝赐教,谢谢!

      参考链接:

        Worker: https://developer.mozilla.org/zh-CN/docs/Web/API/Worker/Worker

        Function support: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Functions_and_classes_available_to_workers#Comparison_of_the_properties_and_methods_of_the_different_type_of_workers

        Worker loader: https://www.webpackjs.com/loaders/worker-loader/

     

    转载于:https://www.cnblogs.com/gerry2019/p/11456035.html

    展开全文
  • Vue使用Web Worker

    千次阅读 2019-10-24 15:55:44
    webpack提供了一个loader叫做worker-loader,用来实现web worker的功能。 安装:npm i -D worker-loader 在build/webpack.base.conf.js的rules中添加如下配置: { test: /\.worker\.js$/, //以.worker.js结尾的...

    webpack提供了一个loader叫做worker-loader,用来实现web worker的功能。

    1. 安装:npm i -D worker-loader
    2. 在build/webpack.base.conf.js的rules中添加如下配置:
    {
         test: /\.worker\.js$/, //以.worker.js结尾的文件将被worker-loader加载
         use: {
              loader: 'worker-loader' ,
              options: { inline: true, name: 'workerName.[hash].js' }
         }
    }
    
    1. 新建webworker.worker.js文件:
    onmessage = function(evt){
       //工作线程接收到主线程的消息
    	......
    	
      //向主线程发送消息
      postMessage(data);
    };
    
    //错误信息
    onerror = function (event) {
      console.log(event.message);
    }
    
    1. 在需要的组件中:
    import Worker from './webworker.worker.js';
    
    // 创建 worker 实例
    var worker = new Worker();
    
    //向工作线程发送消息
    worker.postMessage({
          colLength:colLength,
          rowLength:rowLength,    
    });
    
    worker.onmessage = function(event) {
    	//主线程接收到工作线程的消息
    	......
     	
     	//关闭线程
     	worker.terminate();
    }
    
    展开全文
  • vue WebWorker使用

    2021-02-23 15:00:43
    webworker 我们知道javascript是单线程,当主线程遇到大量计算或者复杂的业务逻辑时,会对我们的页面造成不好的用户体验。 webworker 很好的解决了这个问题,我们可以在主线程开启一个worker线程执行任务而不干扰...

    webworker

    我们知道javascript是单线程,当主线程遇到大量计算或者复杂的业务逻辑时,会对我们的页面造成不好的用户体验。
    webworker 很好的解决了这个问题,我们可以在主线程开启一个worker线程执行任务而不干扰用户界面(主线程)

    worker描述

    感觉还是有点抽象,举个例子。
    那撸多(鸣人)这个5s真男人跟佩恩打架,开启了仙人模式,然而他的查克拉不够用,只能维持五秒钟仙人模式,他自己又不能一边打架一边聚集查克拉。这可怎么办?出了穿甲装的佩恩,一刀一个那撸多
    这个时候那撸多灵机一动,想起了那个延时保健的小药丸…
    咳咳,当然不是,我们大男主利用影分身在看不见的地方凝聚查克拉,凝聚完毕接触分身能量回到主体,嗯来劲了。成功打败佩恩
    这里的影分身就相当于worker的作用,一个在你看不见的地方(其实是在浏览器中)默默工作的奉献者。在合适的时候将结果回传给主线程,然后消失,像是没来过一样

    worker api使用

    主线程中

    Worker.onerror:指定 error 事件的监听函数。
    Worker.onmessage:指定 message 事件的监听函数,发送过来的数据在Event.data属性中。
    Worker.onmessageerror:指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件。
    Worker.postMessage():向 Worker 线程发送消息。
    Worker.terminate():立即终止 Worker 线程。
    

    示例

    	//实例化一个线程
    	let myworker = new Worker('worker.js')
    	//向worker线程 发送信息
    	myworker.postMessage({name:'kk',finshed:false})
    	//接受worker线程 
    	myworker.onmessage = (event)=>{console.log(event.data)}
    	//关闭worker线程 worker 线程会被立即杀死,不会有任何机会让它完成自己的操作或清理工作。
    	myWorker.terminate();
    	```
    	在worker.js中
    	```js
    	//监听接收 主线程的参数
    	onmessage = function(event){
    		// you can  start ajax
    		let result = ...
    		//将计算结果回传给主线程
    		postMessage(result);
    		//workers 也可以调用自己的 close  方法进行关闭
    		close();
    		//self.close()
    	}
    	onerror = function (event) {
    	 console.log(event.message);//可读性良好的错误消息
    	 console.log(event.filename)//发生错误的文件名
    	 console.log(event.lineno) //发生错误时所在脚本文件的行号	 
    	 self.close() 
    	}
    	
    
    
    注意: 在主线程中使用时,onmessage和postMessage() 必须挂在worker对象上,
    而在worker中使用时不用这样做。原因是,在worker内部,worker是有效的全局作用域。
    

    worker 线程中

    self.name: Worker 的名字。该属性只读,由构造函数指定。
    self.onmessage:指定message事件的监听函数。
    self.onmessageerror:指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件。
    self.close():关闭 Worker 线程。
    self.postMessage():向产生这个 Worker 线程发送消息。
    self.importScripts():加载 JS 脚本。
    

    在vue里的配置以及使用

    安装worker-loader

    npm install worker-loader --save-dev
    

    文件代码

    	### vue.config.js 文件
    	
         config.module
          .rule("worker-loader")
          .test(/\.worker\.(c|m)?js$/i)
          .use("worker-loader")
          .loader("worker-loader")
          .options({
            filename: "[name].[contenthash].worker.js",
          })
          .end();
    
    	### my.worker.js 文件
    	//引入js 文件
    	// 脚本的下载顺序不固定,但执行时会按照传入 importScripts() 中的文件名顺序进行。
    	//这个过程是同步完成的;直到所有脚本都下载并运行完毕,importScripts() 才会返回
    	importScripts('foo.js', 'bar.js','ajax.js'); 
    	onmessage = function(event){
    	  //工作线程接收到主线程的消息
    	  
    	 let data = 10
    	 //向主线程发送消息
    	 console.log(event.data);
    	 postMessage(data);
    	};
    	
    	### file.vue 文件
    	  import Worker from "@/utils/my.worker.js";
    	  mounted() {
    	    this.worker = new Worker();
    	    // console.log(this.worker);
    	  },
    
    
    

    worker注意的点

    1.同源限制
      Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。
    2. DOM限制
      document、window、parent这些对象。但是,Worker 线程可以navigator对象和location对象
    3.脚本限制
      Worker 线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。
    4.文件限制
     Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络
    

    应用场景

    1.轮询更新数据状态
    2.复杂数据处理场景,加密数据
    3.大文件上传(小作者我就是开发这个,接触了worker)
    4.预加载图片(当然最好懒加载)
    

    webworker兼容性

    点击这里查看兼容性

    参考文档

    Worker使用教程
    worker MDN

    展开全文
  • 第一步 先在store中声明好需要存储的数据。 state: { testName: 'hello', ...创建一个worker文件,连接websocket let WS let lockReconnect = false // 避免重复连接 const webWorkerSelf = self co...

     

      第一步

    先在store中声明好需要存储的数据。

     state: {
        testName: 'hello',
       
      },
    mutations: {
        setTestName(state, name) {
          state.testName = name
        }
    }

    创建一个worker文件,连接websocket

    
    
    let WS
    let lockReconnect = false // 避免重复连接
    const webWorkerSelf = self
    const HeartBeat = {
      msgType: 'U',
      msgData: {
        ip: '127.0.0.1',
      },
      dataType: 'keepAlive',
    
    
    }
    //主线程
    self.addEventListener(
      'message',
      function(e) {
        const data = e.data
        switch (data.cmd) {
          case 'sendOnline':
            heartCheck.sendOnline()
            break
          case 'config':
            Object.assign(HeartBeat.msgData)
            break
          case 'start':
            self.postMessage({
              type: 'webWorker',
              data: '启动webWorker'
            })
            createWebSocket()
            break
          case 'stop':
            WS.close()
            self.postMessage({
              type: 'webWorker',
              data: '停止webWorker'
            })
            // 服务器断开链接
            self.postMessage({
              type: 'keepalive',
              data: 'close' + new Date().toTimeString()
            })
            self.close() // 终止worker
            break
          default:
        }
      },
      false
    )
    
    
    const createWebSocket = function() {
      if (!WS) {
        WS = new WebSocket(url)
        WS.onerror = function(event) {
          reconnect(url)
        }
        WS.onclose = function(event) {
          reconnect(url)
        }
        WS.onopen = event => {
          // 服务器开启链接
          webWorkerSelf.postMessage({
            type: 'keepalive',
            data: 'start' + new Date().toTimeString()
          })
          heartCheck.reset().start() // 传递信息
        }
        WS.onmessage = e => {
          // 如果获取到消息,发送给主线程
          const data = JSON.parse(e.data)
          self.postMessage({
            type: 'webSocket',
            data
          })
          heartCheck.reset().start()
        }
      }
    }
    /***
     * 心跳检查
     * @type {{timeoutObj: null, start: heartCheck.start, reset: heartCheck.reset, timeout: number}}
     */
    const heartCheck = {
      timeout: 30 * 1000, // 检查时间
      timeoutObj: null,
      serverTimeoutObj: null,
      reset: function() {
        clearTimeout(this.timeoutObj)
        clearTimeout(this.serverTimeoutObj)
        return this
      },
      // 发送在线信息
      sendOnline: function() {
        if (WS.readyState === 1) {
          WS.send(JSON.stringify(HeartBeat))
        }
      },
      close: function() {
        this.serverTimeoutObj = setTimeout(() => {
          // 如果超过一定时间还没重置,说明后端主动断开了
          // 服务器断开链接
          webWorkerSelf.postMessage({
            type: 'keepalive',
            data: 'close' + new Date().toTimeString()
          })
          WS.close() // 如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
        }, this.timeout)
      },
      start: function() {
        this.timeoutObj = setTimeout(() => {
          // 这里发送一个心跳,返回一个心跳消息
          // onmessage拿到返回的心跳就说明连接正常
          this.sendOnline()
          this.close()
        }, this.timeout)
      }
    }
    
    /**
     * websocket重连
     */
    function reconnect(url) {
      if (lockReconnect) return
      lockReconnect = true
      // 没连接上会一直重连,设置延迟避免请求过多
      setTimeout(function() {
        WS = null
        createWebSocket()
        lockReconnect = false
      }, 2000)
    }
    

    新建一个websocket文件将worker文件引入

    <template>
      <div></div>
    </template>
    
    <script>
    import Worker from './min.worker.js'
    
    
    
    export default {
      name: 'socketView',
      data() {
        return {
          webSocket: null
        }
      },
      created() {
     
        this.initWebSocket()
    
      },
    
      methods: {
        initWebSocket() {
          const that = this
          // 用webworker子线程去连接webSocket
          this.webSocket = new Worker()
     
          this.webSocket.postMessage({ cmd: 'start' })
          this.webSocket.onmessage = function(event) {
            const { type, data } = event.data
            if (type === 'webSocket') {
                 //这里调用store中的dispath或者commite储存数据
        
            } else if (type === 'keepalive') {
              //console.log('keepalive')
             
              if (data === 'close') {
                //
                //console.log('close')
              }
            }
          }
        },
        
      },
      beforeUnmount() {
        this.webSocket.postMessage({ cmd: 'stop' })
        setTimeout(() => {
          this.webSocket.terminate()
          this.webSocket = undefined
        })
      }
    }
    </script>
    
    <style scoped></style>
    

    再在页面中用computed监听数据,就能实现实时更新了!

    展开全文
  • vue使用 worker-loader 及遇到的问题

    千次阅读 2020-08-05 19:05:09
    Web Worker 使用教程 Worker - Web API 接口参考 | MDN 版本 Vue CLI 3 webpack 4 worker-loader 3 vue-cli3 中依赖的 webpack 版本是 "webpack": "^4.0.0",而 "worker-loader": ...参考:vue使用web worker webp
  • Web Workervue中的使用

    2021-02-18 15:56:33
    // 注册之后就在Vue的原型对象上挂载了$worker,您可以使用this.$worker来访问使用worker .vue文件中 // 通过this.$worker.run这个方法,跑起一个worker, // worker是在另外的线程里面跑的,所以可以在run的第一...
  • 这是由Rollup.js捆绑提供的使用WorkerDOM在Web Worker中工作的Vue.js的“ hello world”演示应用程序。 Web Worker中的Vue.js这是Vue.js的“ hello world”演示应用程序,由Rollup.js捆绑使用WorkerDOM在Web Worker...
  • Bug 在代码中直接使用worker会报错,如下图所示 Solution
  • Web Worker,JS多线程,vue-worker

    千次阅读 2020-05-29 17:36:17
    阮一峰文档介绍web worker 摘录: 一、概述 JavaScript 语言采用的是单线程模型,也就是说,所有任务只能在一个线程上完成,一次只能做一件事。前面的任务没做完,后面的任务只能等着。随着电脑计算能力的增强,...
  • webworker在js与vue中的使用

    千次阅读 2020-08-28 18:19:12
    worker在js与vue中的使用
  • js使用webWorker实现多线程 原生js使用worker index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,...
  • vue-worker的介绍和使用

    千次阅读 2019-11-14 11:21:04
    vue-worker把复杂的web worker封装起来,提供一套非常简明的api接口,使用的时候可以说像不接触worker一样方便。那么具体怎么使用呢? 安装 npm i -S vue-worker 注册 import Vue from 'vue'import ...
  • 基于webassembly的H265视频播放器前端Angular学习笔记6:使用WebWorker加载Wasm使用WebWorker加载Wasm创建组件与路由创建Worker加载Wasm开启worker测试结果 本文基于开源项目decoder_wasm使用Angular开发的前端页面...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,854
精华内容 1,941
关键字:

vue使用webworker

vue 订阅