介紹
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項目中使用
- 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的相關文檔來體驗這種編程,希望對你有所幫助!