介绍
Hamsters是一个能让JavaScript代码并行执行的原生库,它可以让你面向高性能的JavaScript编程,它是一个开源项目,Github上标星4k+。它的目的就是让你更加容易的利用多线程的强大功能来并行编程实现性能的提升!
Github
https://github.com/austinksmith/Hamsters.js
特性
- 多功能,通过跨多个线程来最大限度地提高性能。
- 自动数据聚合,自动将问题分解成较小的部分,并与单个输出并行执行。
- 自动分类,按字母顺序或数字自动排序输出。
- LEGACY 支持。
- 备忘,计算一次后不再浪费 cpu 周期做同样的工作
- 开放源代码,100%开源代码库,根据Artistic License 2.0发布
支持的环境
- 所有主流浏览器、IE9 +
- 现有 Web workers
- Javascript shell 环境
- React Native
- Node.js
如何使用?
安装使用
- bower install WebHamsters
- //OR
- npm install hamsters.js
- 1、普通HTMl项目中使用
- <!-- HTML4 and (x)HTML -->
- <script type="text/javascript" src="path/to/hamsters.js">
- <!-- HTML5 -->
- <script src="path/to/hamsters.js"></script>
- 2、React Native
- import hamsters from 'path/to/hamsters';
- import Worker from '...';
- import hamsters from 'hamsters.js';
- hamsters.init({
- Worker: Worker
- });
- 3、Nodejs
- var hamsters = require('hamsters.js');
- var Worker = require('...').Worker;
- var hamsters = require('hamsters.js');
- hamsters.init({
- Worker: Worker
- });
- 4、入门使用
第一个要理解的是Hamsters.js是一个传递interfafce的消息,因此在使用库调用函数时,我们需要通过将params对象(消息)传递给库来指示库如何操作。
- var params = {
- bar: 'foo'
- };
- hamsters.run(params, ....);
我们将使用的下一个参数将是我们想要在一个线程或线程中执行的逻辑,我们之前传递的params对象将在我们的函数的上下文中可访问。现在应该能够看到如何确保可以在线程中访问变量和函数等不同的东西。
- hamsters.run(params, function() {
- var foo = params.bar;
- });
第三个也是最后一个参数将是我们的onSuccess回调方法,此函数所需的唯一参数是输出。
- hamsters.run(params, function() {
- var foo = params.bar;
- }, function(results) {
- console.log(results);
- });
回到原始的params对象,为了从库中获得最佳性能和可靠性,需遵循一些约定。Hamsters.js的构建目标是并行而不是并发,尽管库很好地实现了并行执行的主要目标。由于这样做的各种设计决策是为了帮助实现这一目标,其中一个决定是库如何在线程之间分割数据以便执行,因此您希望在多个线程中访问的任何数组必须在您的参数内具有数组索引宾语。
- var params = {
- array: [1, 2, 3, 4];
- };
- hamsters.run(params, function() {
- for(var i = 0; i < params.array; i++) {
- rtn.data.push(params.array[i] * 4);
- }
- }, function(results) {
- });
使用此约定,通过简单地更改params对象中的一个选项,可以非常简单地并行化上述方法。现在使用下面的方法,4个线程将完成相同的任务,每个线程仅在数组的一个数字上运行。
- var params = {
- array: [1, 2, 3, 4];
- threads: 4
- };
- hamsters.run(params, function() {
- for(var i = 0; i < params.array; i++) {
- rtn.data.push(params.array[i] * 4);
- }
- }, function(results) {
- });
更进一步,库使用一个名为rtn的内部返回对象,这个rtn对象对于库具有一致的方式来处理线程输出是至关重要的。因此,当我们想要从线程返回一个值时,我们需要将结果推送到rtn.data数组中。或者你可以让你的rtn.data输出,但只有当你的输出已经是一个数组。
- hamsters.run(params, function() {
- rtn.data.push(params.bar);
- }, function(results) {
- console.log(results); // 'foo';
- });
通过以上代码来看下它传递的参数:
- var params = {
- threads: Integer,
- aggregate: Boolean,
- dataType: String,
- memoize: Boolean
- sort: String,
- };
1、threads这个可选参数将告诉库执行先前声明的函数的线程数,这允许在非常简单的级别上更改您执行的线程数。如果您在此处未提供值,则库默认值为1。
2、aggregate此可选参数将告诉库我们是否要在执行后将各个线程输出聚合在一起,这仅在您跨多个线程执行并且默认为相关时才相关false。
3、dataType此可选参数将通知库我们的数据数组是JavaScript的类型化数组之一,在使用此参数时,库将自动格式化输出以匹配指定的输出dataType。
4、memoize此可选参数旨在与memoization模式结合使用,当启用memoization模式时,此参数允许用户控制单个函数级别是否缓存该函数的结果,其默认值为false。
5、sort此可选参数将告诉库按字母顺序或数字顺序自动对最终输出进行排序,此参数的默认值为,null并且可以使用排序选项进行配置。
params对象中包含的任何其他内容都可以在线程的执行上下文或多个线程中访问,具体取决于您使用库的方式。
除了以上基本使用方式,你可以查看官方的相关文档,有详细的介绍和使用方式,如Promise、排序、memoization、可转移对象、persistence、线程池、限制、设备等
总结
多线程和并行编程在Javascript中本身不是一件容易的事情,但是可借助第三方原生库来弥补它,能让你更加方便的进行多线程的编程,笔者可能并未介绍的非常清楚,如果你有这方面的需求,可以去查案Hamsters.js的相关文档来体验这种编程,希望对你有所帮助!