WebWorker

WebWorker:浏览器的 "异步执行"

介绍:https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API


WebWorker与异步任务

在一般的异步任务如ajax, 计时器等等,都会交给浏览器相应的异步模块去执行,在执行过程中不会阻塞主线程的操作。那么当我们需要做一些自定义复杂的计算时(没有现成的web api),如果直接放在主线程执行,会阻塞整个页面,无法进行别的操作。这时候就可以使用webworker开辟一个子线程,让计算在子线程中执行,而不会影响到主线程。


可以在Worker线程中做什么?

  1. 网络操作(Ajax、Socket)
  2. 计时器操作
  3. 访问某些重要全局变量及功能的复本
  4. 做复杂度较高的计算

注:Worker线程中不能操作DOM、不能使用全局变量/对象/函数。

1. 用来进行计算

父进程

      let worker = new Worker("/static/worker.js");

        //发送消息到worker.js中
      worker.postMessage({
        type: "all",
        id: 2
      });

      // 接收worker的消息
      worker.addEventListener("message", function (e) {
        console.log("接收消息", e.data.content); //sum:101
      })

子进程:这里做个简单的计算

// worker.js
self.addEventListener('message',function(event){
      let arr = [1,2,3,4,4,5,6,7,8,5,5,3,2,2,4,5,6,7,5,3,3,5,6,];
      let sum = arr.reduce((pre,cur)=>{
        return pre+cur
      });

      self.postMessage({
        type:'all',
        content:sum
      });
});

2.用来发送ajax请求

当页面中存在很多图片需要加载时,经常会用到懒加载。但也有特定的需求需要一次性加载所有图片,这时候可以用子线程来加载

worker.js


(function(){
  let arr = ['http://img3.imgtn.bdimg.com/it/u=3307014006,766424055&fm=15&gp=0.jpg',
          'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
          'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
          'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
          'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
          'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
          'https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
          'https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg'];
for (let i = 0, len = arr.length; i < len; i++) {
    let req = new XMLHttpRequest();
    req.open('GET', arr[i], true);
    req.responseType = "blob";
    //req.setRequestHeader("client_type", "DESKTOP_WEB");
    req.onreadystatechange = () => {
      if (req.readyState == 4) {
      postMessage(req.response);
    }
  };
  req.send(null);
}
})();

主线程:

let w = new Worker("/src/js/worker/worker.js");
  w.onmessage = function (event) {
    let img = document.createElement("img");
    img.style.width = '100%';
    img.src = window.URL.createObjectURL(event.data); // 把图片blob对象转变成url

    document.querySelector('#result').appendChild(img)

    console.log(event.data);
 };

 w.onerror = function(e){
     // e.currentTarget.terminate();
    console.log('erro: ' + e.message);
};

 


Vue-worker

Vue-Worker把复杂的web worker用Promise封装起来,提供一套非常简明的api接口

安装 

npm i -S vue-worker

注册 

import VueWorker from 'vue-worker'

Vue.use(VueWorker)

使用 :结合create([...actions])和postMessage使用,可以在create钩子函数中定义每个message对应哪个处理函数,然后直接使用worker.postMessage来调用并传参。子线程中把结果return 出来,父线程用then来触发回调。

      //父线程
      create(){
         this.worker = this.$worker.create(
         [
          {
            message: 'calc',
            func:worker.calcSomeThing
          },
          //{...}
         ]);
      }

      methods:{
        docalc(){
            let data = [1,2,3,4,5,6,5];
            this.worker.postMessage('calc', [data]).then(res =>{
              console.log(res); // sum is: 26
            })
        }  
      }
     
// worker.js
function calcSomeThing(arr){
  return 'sum is:'+arr.reduce((pre,cur)=>{
    return pre+cur
  })
}

 


run方法结合了create和postMessage,调用更为方便,但run是一次性的,跑完这次,worker线程就会被关掉。

     
  this.worker = this.$worker.run(worker.calcSomeThing).then(res=>{
     console.log(res) // sum is:55
   }).catch(e=>{
     console.log(e)
   })
// worker.js
function calcSomeThing(){
  let arr = [1,2,3,4,5,6,7,8,9,10];
  return 'sum is:'+arr.reduce((pre,cur)=>{
    return pre+cur
  })
}

export default {
  calcSomeThing
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值