JS进阶

  1. JS进阶
    1. 子线程处理

JS进阶

子线程处理

问题:今天做到一个需求要求前端上传文件时检查MD5值,这里使用了spark-md5来分块计算MD5值。在小文件计算时非常顺利,在上传一个700MB文件的时候就出现了线程明显的卡断,导致整个Vue页面未响应了几秒才开始上传文件。

原因剖析

JavaScript在前端是异步单线程的,如果要计算一个大文件md5值会导致主线程直接被阻塞掉,UI界面自然会未响应。

这里采用创建子js线程的方式,并且以Promise的方式来异步的获取结果。

  • var myWorker = new Worker('../js/md5Worker.js'); 创建一个MD5工作线程对象
  • myWorker.postMessage([file]); 需要传入线程的参数数组,这里传递了文件信息。
  • myWorker.onmessage = onMessage; 绑定回调方法

这样子el-upload组件就会在工作线程完成md5解析工作后获取到返回异步操作结果,然后执行上传的逻辑。

el上传前钩子

beforeUpload(file){  

  /*推送上传消息*/
  let info = {
    /*文件uid*/
    uid:file.uid,
    /*文件名*/
    name:file.name,
    /*状态*/
    status:null,
    /*进度条百分比*/
    progressPercent:0,
  };

  this.$store.state.uploadInfoMap.set(file.uid,info);
  this.$store.commit('uploadStart');

 return new Promise((resolve, reject) => {
   /*创建一个新线程去处理*/
   var myWorker = new Worker('../js/md5Worker.js');
   /*为线程传递消息*/
   myWorker.postMessage([file]);
   /*计算函数*/
   let md5;
   let onMessage = (e)=>{
     {
       md5 = e.data;
       file.md5 = md5;
       resolve();
     }
   }
   /*绑定回调方法*/
   myWorker.onmessage = onMessage;
 })
},

worker子线程

importScripts('../utils/spark-md5.js');

self.onmessage = function(e) {
 /*   console.log('Message received from main script');*/
    
    let fileReader = new FileReader()
    let spark = new SparkMD5.ArrayBuffer() // 创建md5对象(基于SparkMD5)
    fileReader.readAsArrayBuffer(e.data[0]) // file 对应上传的文件

    // 文件读取完毕之后的处理
    fileReader.onload = (e) => {
        spark.append(e.target.result);
        let md5 = spark.end();
       /* console.log('Posting message back to main script');*/
        self.postMessage(md5);
    }

}

通过e.data[index] 来获取传入的参数

调用self.postMessage(result) 来返回结果


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1300452403@qq.com

文章标题:JS进阶

字数:509

本文作者:Os467

发布时间:2024-01-05, 02:36:43

最后更新:2024-01-05, 02:36:53

原始链接:https://os467.github.io/2024/01/05/JS%E8%BF%9B%E9%98%B6/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

×

喜欢就点赞,疼爱就打赏