近期项目需求中,计算量导致 ui 卡顿,决定将这部分逻辑放入 web worker 中计算,由于 TypeScript 的问题,莫名其妙的报错导致花费了一下午的时间。
Angular 中使用
在 angular8 中可以直接运行命令 ng generate webWorker my-worker
开启功能。
- 会修改 angular 工程中部分配置:生成针对 webworker 的 tsconfig 配置
- 生成一个 worker 工作示例
Worker 需要通过网络来加载一个脚本,如何配合 webpack 来自动化完成这件事情呢,你可以使用下面的语法,angular-cli 会自动进行代码分割
const worker = new Worker(`./my-worker.worker`, { type: `module` });
踩的坑
编译卡住
主线程中负责创建 Worker 对象的文件 A,如果 worker.js 中也 import 文件 A 中某些函数,会导致编译卡住。具体不知道是不是这个原因,但将代码拆分出来,问题也就解决了。
数据限制
还有你需要知道 web worker 中通信数据的限制,类似于网络传输中序列化与反序列化。虽然 web worker 会对 message 自动进行序列化与反序列。但你需要知道这样的后果就是,如果传递对象,会导致原型链丢失,也就是说对象中的函数会丢失,且原型链直接指向 Object。
看到这里,突然就明白了一些第三方库提供 toJSON 和 fromJSON 的目的了。所幸我的例子中,jsts 提供了 geojsonWriter 和 geojsonReader 函数,可以达到我们的目的。
变异报 require 相关错误
在修改 tsconfig 的过程中发现,导致 require 函数报错的原因是 tsconfig 的 types 字段需要包含 node
。
变异报类型错误
针对 worker 的 tsconfig 比较特殊,由于 web worker 不能访问 dom 元素。因此需要将 lib 中 dom
修改为 webworker
。且这两者是不能同时存在的。
这里有个巨大的坑,就是我们引用的第三方库很可能引用 dom 中才有的类型声明,从而导致居多的错误。你可以设置 skipLibCheck: true
来跳过第三方库检查。