如何更爽的在 JS 中使用多线程

zy445566:最近写多线程的时候遇到一个烦恼,就是用起来实在太麻烦,不管是 WebWorker 还是 worker_threads 库,用起来都实在太麻烦了。而且很多时候 IO 密集和 CPU 密集操作很多时候是交织的,有没有一种办法,可以直接在代码中方便的使用多线程呢?

以前我们使用 Worker 要怎么做?现在我们能怎么做?

之前的做法:

// ### 父进程代码
// 比如请求网络数据,IO 操作
const apiData = await request('/api/xxx');
// 为了不阻塞 eventloop 开启子线程,并拿到符合要求的格式
const goodApiData = await new Promise((resolve, reject) => {
  const worker = new Worker('子进程文件名 xxx.js', {
    workerData: apiData
  });
  worker.on('message', resolve);
  worker.on('error', reject);
});
// ### 子线程代码
// 这里处理 data 数据,CPU 密集操作
doSomething(workerData)
// 再发送回父进程
parentPort.postMessage(data);

代码量这么大,还要写 2 个文件以上文件,数据发送过去再发送回来头都大了!!!费脑!!!

那有没有更好的方法呢?当然使用 ncpu 就能做到!

使用 ncpu 的做法:

import {NCPU} from 'ncpu'
// 比如请求网络数据,IO 操作
const apiData = await request('/api/xxx');
// 为了不阻塞 eventloop 开启子线程,并拿到符合要求的格式
const goodApiData = await NCPU.run((data)=>{
  // 这里处理 data 数据,CPU 密集操作
  doSomething(data)
  return data;
}, [apiData]) //使用数组传参,这有点类似 apply

使用 ncpu 果然爽,一个回调函数就把 CPU 密集型计算搞定了。

爽是爽,但目前有两点强制限制:

  • 回调函数不能共用上下文,因为 ncpu 是使用函数复制的方式来实现的,不会保留函数上下文,所以要求函数是强无副作用函数。
  • 传入参数都是使用 HTML structured clone algorithm方式来进行克隆的,而非原值。

但正是这两点强制限制,使得线程更加安全了。因为但多个线程同时操作原值,会导致内存数据更新速度赶不上线程更新的速到,导致另一个线程读取数据不正确。而且我们要处理数据时,通常只需要将大循环和递归计算放入线程的回调函数中,所以这两点强制,反而不是坏事。

目前 ncpu 的两个版本

一个是ncpu专门为 node.js 环境设计,另一个是ncpu-web专门为浏览器环境设计。

同时ncpu需要的最低 node.js 版本是 12,而ncpu-web浏览器要求是谷歌浏览器至少 60 以上,火狐 57 以上即可。

在使用的时候要注意这些问题哦!

way2explore2:我最近写了一个多进程的工具。pambdajs

https://github.com/tim-hub/pambdajs

zy445566:@way2explore2 天呐!我们想到一块去了!棒!你文档比我写的好,但我多了个前端版本,哈哈

这个网站是 Node.js 搭建的吗?

yunyingsilue:小弟不懂,想问问大家www.ruanfa.cn这个网站是 Node.js 搭建的吗?能不能看出来Node.js 搭建的网站有哪些优缺点?putaozhenhaochi:这就是你想出来的推广方式? imherer:是的,用的 next.js SingeeKing:不说是不是推广,看软件介绍里面的图我有点想 @1ychee jimmy2…

Symfony2和Selectize.js:在实体字段类型中保留新项目的最清晰方法? - php

在Symfony2中,我具有BandType,在其中添加实体Tag:->add('tags', 'entity', [ 'label' => 'Tags', 'class' => 'DbBundle:Tag', '…

Backbone.js Visual Studio设置 - javascript

我正在尝试在Visual Studio中设置Backbone.js,下面链接的指南告诉我,我需要安装BackBoneSpa.vsix,但由于它是Visual Studio文件扩展名,因此我需要安装ASP.net Web Tools 2012。向您的visualstudio C#项目中添加骨架.js的唯一方法?http://www.asp.net/single…

流数据解决方案(Java,Python,socket.io,Node JS) - java

我正在一个项目中,我需要将财务数据流式传输到Web浏览器。我从数据提供者那里获得了Java API(我不太擅长Java),可以将数据流传输到服务器。数据输入后,我需要对其进行一些计算,并将其存储在MongoDB数据库中,并将其发送给任何连接的客户端。如果我不想使用Java,那么构建解决方案的最佳选择是什么?我当时在考虑使用Node的socket.io,但不确…

将C#代码插入(.js)javascript文件 - c#

在asp.net mvc 3应用程序中,我有两个视图具有相同的javascript函数集。 Javascript是相同的,因此我想重新组织这段代码并将所有JavaScript代码提取到.js文件中,以便将其包含在两个chtml文件中。问题在于,其中一个javascript函数使用C#代码来从模型中获取一些数据。如何将C#代码插入到javascript(.js…