首页 > 建站教程 > 前端框架 >  worker报错:Failed to execute 'postMessage' on 'Worker': could正文

worker报错:Failed to execute 'postMessage' on 'Worker': could

我爱模板网在利用input webkitdirectory做文件夹上传时,一次性选择的文件达到了10000个,选择文件后,需要对文件一个一个进行遍历,以便于显示在当前列表,这是一个非常耗时的操作,最终决定利用worder重开一个子线程进行操作。于是便有了下面的代码:
<input type="file" name="file" webkitdirectory @change="onPickDirectory($event)">

onPickDirectory(e) {
  const that = this;
  that.loading2 = true
  that.loading2Text = '正在加载文件,请稍后...'
  worker.postMessage(e);
  var worker = new Worker('work.js');
  worker.onmessage = function (event) {
    that.fileList = event.data;
    that.loading2 = false
    that.loading2Text = ''
    //结束
    worker.terminate();
  }
},
运行起来报错:
Failed to execute 'postMessage' on 'Worker': could not be cloned.

意思是发送给子线程的数据不能被克隆,下面是百度来的Web Worker几个使用注意点:
(1)同源限制
    分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。
(2)DOM 限制
    Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。但是,Worker 线程可以navigator对象和location对象。
(3)通信联系
    Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。
(4)脚本限制
    Worker 线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。
(5)文件限制
    Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。

我估计是因为这个event包含了一些不可clone的对象,于是,将event的其他信息去掉,只留下files,再传递,就没问题了:
onPickDirectory(e) {
  const that = this;
  that.loading2 = true
  that.loading2Text = '正在加载文件,请稍后...'
  that.scaned = false
  var worker = new Worker('work.js');
  const files = e.target.files
  worker.postMessage(files);
  worker.onmessage = function (event) {
    that.fileList = event.data;
    that.loading2 = false
    that.loading2Text = ''
    //结束
    worker.terminate();
  }
},
work.js代码:
self.addEventListener('message', function (e) {
    const files = e.data;
    const temp = []
    for (const i in files) {
      const curFile = {}
      if (!files[i].name || !files[i].webkitRelativePath) continue
      curFile.file = files[i] // 存储的源文件对象,用来上传
      curFile.name = files[i].name.substring(0, files[i].name.lastIndexOf('.'))
      curFile.webkitRelativePath = files[i].webkitRelativePath
      curFile.size = calcSize(files[i].size)
      curFile.type = files[i].name.split('.')[files[i].name.split('.').length - 1]
      curFile.lastModified = timeStamp2Date(files[i].lastModified)
      temp.push(curFile)
    }
    self.postMessage(temp);
    self.close();
}, false);