workerData
这一个属性,通过 代码 13.1.2 worker.js 可以看出,它被注入到了子线程的上下文中了,可以通过读取 require('worker_threads').workerData
来直接获取它的值。postMessage
函数。V8 内部在实现 postMessage
函数的时候,会将传递的数据先在内部做序列化为二进制,然后将序列化后的二进制数据追加到接收线程的内部队列中;同时发送者还会在拷贝还会触发一个信号量,通知对端线程有新数据到来,对端线程在收到这个通知后,会通过反序列化将数据还原。postMessage
函数支持传递 ShareArrayBuffer
类型的数据,使用这个类型之后,父子进程之间无需做数据拷贝和序列化,但是实际生产环境中我们操作二进制数据的情况比较少,一般是通过传递 js 对象来进行相互通信,所以这个功能用到的机会很少。同时留意到 postMessage
函数的第二个参数支持传递一个数组,里面可以放 ArrayBuffer
类型的数据,且存放的变量需要和第一个参数是同一个变量,代表当前数据发送到对端线程后,本端线程将直接销毁掉这个变量,这样可以加快 GC 的过程,但是由于大家二进制用到的情况少,所以这个功能应该也会很少用到。req1
req2
,对应的处理 HTTP 响应的对象 res1
和 res2
,这两个响应对象底层关联的是同一个 socket 句柄,用户端在书写代码的时候尽管写响应对象的 send 函数即可,Node 底层在处理的时候会先发 res1 的响应,后发 res2 的响应。但是同样的情况换成 Web Worker 之后,这种请求的先后顺序在子线程中无感,也就无从处理这种先后顺序,很容易导致客户端接收到乱序的数据从而解析失败。不过上面的例子多少有些不合时宜,因为目前 Web Worker 在调用 postMessage
的时候仅仅只能传简单对象,对于上面这种含有 socket 属性的数据是不能传递的。这里仅仅是举一个让大家更容易理解的例子,大家可以依此展开联想。key2
,用户请求 key2
的 请求被分配到进程 1 上时,就会出现缓存击穿的问题,明明在进程2 上含有 key2
的数据,但是进程 1 感知不到。BroadcastChannel
的 API,算是对上述行为的“僭越”了。V8 原生的 Web Worker 毕竟设计初衷是为了应对前端计算密集型的场景,Node 官方最终也算是看出来它的不足。我大胆猜测,以后会有更多超出 V8 原生 API 的自定义 API 出现。目前的 Web Worker 在 Node 领域还只是一个初生牛犊,未来还需要茁壮成长。