众所周知,JavaScript 是以单线程的方式运行的,而说到线程,很自然的就能联想到进程。进程线程是什么,它们又有什么关系呢?




typescript 实现多接口_单线程

Javascript



「 题外话 」进程和线程都是操作系统中概念,而进程又是操作系统的重中之重,简单点说进程就是程序执行的动态过程,而进程中的进程控制块PCB,又是操作系统中最重要的数据结构 ......

有点扯远了,回归正题,我们从并发(莫要混淆了并行,我们从宏观上来看,各任务都是并行在执行的,而实际CPU上只有一个程序在运行,只不过速度太快了,寄存器也仅仅能跟上它的脚本而已,我们根本无从察觉而已,也就是说宏观上来看是并行的,而微观上却是串行的)的角度来说,每个进程,CPU都为其分配独立的地址空间资源,因为彼此都相互独立,所以各进程之间的通信显得麻烦,CPU在来回切换进程的时候(进程调度中断机制),开销也大,紧接着线程就应运而生了。

线程是进程中的一个实体,共享进程中的资源,说白了线程就是一段可执行单元,自己能跑能跳,能执行任务,但无法脱离进程而独立存在,进程生而生,进程灭而灭 ...... 线程的出现,有效的提高了CPU的利用率。

进程是CPU分配资源的最小单位,线程是CPU调度的最小单位。




typescript 实现多接口_配置文件_02

进程的概念 / 特征



JavaScript 为什么设计成单线程?

JavaScript 作为浏览器脚本语言,主要是实现用户与浏览器之间的交互,及其操作 DOM(Document Object Model),这就决定了它只能是单线程(例:一个线程要求删除 dom 元素,另一线程要求修改 dom 元素,这就带来了冲突),否则会带来十分复杂的同步问题等,为了避免不必要的复杂性,JavaScript 从一诞生开始就是单线程的,成了这门语言的核心特征,将来也不会改变。




typescript 实现多接口_单线程_03

TypeScript



当前项目为 Vue + Typescript 的情况下,该如何实现多线程呢?当然就是 Web Worker 啦,下面说说具体如何配置实现的(假设我们当前项目是用 vue-cli3 脚手架生成,且新建了 vue.config.js 配置文件)。

依赖

需要安装 worker-loader 依赖,更具体的可以 Github 搜索 worker-loader

配置




typescript 实现多接口_Web_04

配置 vue.config.js



const path = require('path');const resolve = (dir) => path.join(__dirname, dir);const prod = process.env.NODE_ENV === 'production';module.exports = {parallel: false,    chainWebpack: config => {        config.module            .rule('worker-loader')            .test('/.worker.ts$/')            .use('worker-loader')            .loader('worker-loader')            .end();        config.output.globalObject(typeof self !== 'undefined' ? self : this);    }};

声明

自定义声明模块,在根目录下新建 shims-custom.d.ts




typescript 实现多接口_Web_05

声明 Worker 模块



declare module 'worker-loader!*' {class MiWorker extends Worker {constructor();}export default MiWorker;}

使用

注意 import 的时候,worker 的路径要写对。

过程:新建 Layer.vue,该文件引入单独要处理 的 [name].worker.ts 文件,实例化,紧接着即可操作;新建 layer.worker.ts 为线程单独处理的内容,具体的开发代码或具体可用的函数和类,可以查看 Web Workers API




typescript 实现多接口_Web_06

layer.vue





typescript 实现多接口_配置文件_07

layer.worker.ts



const worker: Worker = self as any;worker.onmessage = (evt) => {console.log(evt);};




typescript 实现多接口_单线程_08

结果