Web Workers は、HTML5 によって提供される JavaScript マルチスレッド ソリューションです。計算負荷の高いコードを Web ワーカーに渡して、ユーザー インターフェイスをフリーズさせることなく実行できます。
1: Worker の使用方法
Web Worker の基本原理は、Worker クラスを使用して JavaScript の現在のメイン スレッドに JavaScript ファイルをロードし、新しいスレッドを開くことです。これにより、ノンブロッキング実行の効果があり、メイン スレッドとメイン スレッドの間にデータが提供されます。交換された新しいスレッド: postMessage、onmessage。
それでは、どのように使用するか、例を見てみましょう:
JavaScript コードコンテンツをクリップボードにコピーします
-
-
onmessage =関数 (evt){
-
var d = evt.data;
-
postMessage( d );
- }
HTML ページ: test.html
XML/HTML コードコンテンツをクリップボードにコピー
- >
- <html>
-
<<スパン スタイル="width: auto; height: auto; float: none;" id="20_nwp"><a スタイル="text-装飾: なし;" mpid="20" ターゲット ="_blank" href="http://m.sbmmt.com/ cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=head&k0=head&kdi0=0&luki=6&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1 &seller_id=1&sid=45fdcf1cab219561&ssp2= 1&stid=0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id="20_nwl"><スパン スタイル="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">頭 スパン>a>< /スパン>>
-
<メタ http-equiv=" Content-Type" content="text/html; charset=utf-8"/>
- <スクリプト タイプ="text/ <スパン style="幅: auto; 高さ: 自動; float: none;" id="21_nwp">< a style="text-decoration: none;" mpid="21"ターゲット="_blank" href="http://m.sbmmt.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di= 128&fv=0&is_app=0&jk=619521ab1ccffd45&k=javascript&k0=javascript&kdi0=0&luki=9&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=45fdcf1cab219561&ssp2=1&stid=0& t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/ 1183.html&urlid=0" id="21_nwl">< ;スパン スタイル="color:#0000ff;font-size:14px;width:auto;高さ:自動;浮動小数点:なし;">javascriptスパン>a>スパン>">
- //WEB页主回線程
-
var worker =new Worker("worker.js"); //Worker オブジェクトを作成し、新しいオンライン中に実行されるスクリプトの URL
- worker.postMessage("hello world"); //向ワーカー送信データ
-
worker.onmessage =function(evt){ //受信worker传过来のデータ <スパン スタイル="width: auto; height: auto; float: none ;" id="22_nwp">< a スタイル="text-decoration: none;" mpid="22" ターゲット="_blank" href="http://m.sbmmt.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch =0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=����&k0=����&kdi0=0&luki=2&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=45fdcf1cab219561&ssp2=1& stid=0&t=tpclicked3_hc&tu=u1922429&u=http ://www.admin10000.com/document/1183.html&urlid=0" id="22_nwl"><スパン スタイル="color:#0000ff ;font-size:14px;width:auto;height:auto;float:none;">関数数スパン>a>スパン>
-
console.log(evt.<スパン スタイル= "width: auto; height: auto; float: none;" id="23_nwp"><a スタイル="テキスト装飾:なし;" mpid="23" ターゲット="_blank" href="http://m.sbmmt.com/cpro/ ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=data&k0=data&kdi0=0&luki=4&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller _id=1&sid=45fdcf1cab219561&ssp2=1&stid= 0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id= "23_nwl"><スパン スタイル="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">データ< /スパン>a>スパン>); //出ワーカー送信来のデータ
- }
- スクリプト>
-
頭>
- <ボディ>ボディ>
-
html>
Chrome ブラウザで test.html を開くと、コンソールに「hello world」が出力され、プログラムの実行が成功したことが示されます。
この例を通して、Web ワーカーの使用が主に次の部分に分かれていることがわかります
WEB メインスレッド:
1.worker = new Worker( url ) を介して JS ファイルをロードし、ワーカーを作成し、ワーカー インスタンスを返します。
2.worker.postMessage(data)メソッドを通じてワーカーにデータを送信します。
3. worker.onmessage メソッドをバインドして、ワーカーによって送信されたデータを受信します。
4. worker.terminate() を使用してワーカーの実行を終了できます。
ワーカーの新しいスレッド:
1. postMessage(data) メソッドを通じてメインスレッドにデータを送信します。
2. onmessageメソッドをバインドして、メインスレッドから送信されたデータを受信します。
2: Worker にできること
Web Worker の使用方法がわかりました。Web Worker の用途と、Web Worker はどのような問題の解決に役立つでしょうか。フィボナッチ数列の例を見てみましょう。
数学では、フィボナッチ数列が再帰的に定義されていることは誰もが知っています: F0=0、F1=1、Fn=F(n-1) F(n-2) (n>=2, n∈N* )、 JavaScript の一般的な実装は次のとおりです:
JavaScript コードコンテンツをクリップボードにコピーします
-
-
var fibonacci =function(n) {
-
return n
}; -
-
//fibonacci(36)
Chrome でこのメソッドを使用して 39 のフィボナッチ数列を実行するには 19097 ミリ秒かかりますが、40 の計算になると、ブラウザはスクリプトがビジーであることを直接通知します。
JavaScript はシングルスレッドで実行されるため、シーケンスの計算中にブラウザは他の JavaScript スクリプトを実行できず、UI レンダリング スレッドも一時停止されるため、ブラウザはゾンビ状態になります。 Web ワーカーを使用してシーケンスの計算プロセスを新しいスレッドに配置すると、この状況を回避できます。具体的な例を参照してください:
JavaScript コード
XML/HTML コード
国際コード構成
- >
- <html>
-
<<スパン スタイル="width: auto; height: auto; float: none;" id="11_nwp"><a スタイル="text-装飾: なし;" mpid="11" ターゲット ="_blank" href="http://m.sbmmt.com/ cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=head&k0=head&kdi0=0&luki=6&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1 &seller_id=1&sid=45fdcf1cab219561&ssp2= 1&stid=0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id="11_nwl"><スパン スタイル="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">頭 スパン>a>< /スパン>>
-
<メタ http-equiv=" Content-Type" content="text/html; charset=utf-8"/>
- <タイトル>ウェブワーカーフィボナッチ タイトル>
- <スクリプト タイプ="text/ <スパン style="幅: auto; 高さ: 自動; float: none;" id="12_nwp">< a style="text-decoration: none;" mpid="12" ターゲット="_blank" href="http://m.sbmmt.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di= 128&fv=0&is_app=0&jk=619521ab1ccffd45&k=javascript&k0=javascript&kdi0=0&luki=9&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=45fdcf1cab219561&ssp2=1&stid=0& t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/ 1183.html&urlid=0" id="12_nwl">< ;スパン スタイル="color:#0000ff;font-size:14px;width:auto;高さ:自動;浮動小数点:なし;">javascriptスパン>a>スパン>">
-
onload =関数(){
-
var worker =new Worker('fibonacci.js');
- worker.addEventListener('message', function(event) {
-
var timer2 = (new Date()).valueOf();
-
console.log( '结果:'event.<スパン スタイル ="width: auto; height: auto; float: none;" id="13_nwp" ><a スタイル=" text-decoration: none;" mpid="13" target="_blank" href="http://cpro.baidu. com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=data&k0=data&kdi0=0&luki=4&n=10&p=baidu&q=06011078_cpr&rb=0& rs=1&seller_id=1&sid= 45fdcf1cab219561&ssp2=1&stid=0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id="13_nwl"><スパン スタイル= "color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">データスパン>a> スパン>, '時間:' timer2, '使用時間:' ( timer2 - timer ) );
- }、 間違い);
-
var タイマー = (new Date()).valueOf();
- console.log('开開始计算:40','時間:' timer );
- setTimeout(function(){
-
console.log('定時器<スパン スタイル="width: auto; height: auto; float: none;" id="14_nwp" ><a スタイル="テキスト装飾: なし;" mpid="14" ターゲット="_blank" href="http://m.sbmmt.com/cpro /ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=����&k0=����&kdi0=0&luki=2&n=10&p=baidu&q=06011078_cpr&rb=0&rs =1&seller_id=1&sid=45fdcf1cab219561&ssp2=1&stid=0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id="14_nwl"><スパン スタイル="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">関数数スパン>a>span>在计算数列時間执行了', '時間:' (new Date()).valueOf( ) );
- },1000);
- worker.postMessage(40);
- console.log('我在计算数列的時刻候行了', '時間:' (new Date()).valueOf() );
- }
-
スクリプト>
-
<スパン スタイル= "width: auto; height: auto; float: none;" id="15_nwp"><a スタイル="テキスト-decoration: none;" mpid="15" ターゲット="_blank" href="http://m.sbmmt.com /cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=head&k0=head&kdi0=0&luki=6&n=10&p=baidu&q=06011078_cpr&rb=0&rs =1&seller_id=1&sid=45fdcf1cab219561&ssp2 =1&stid=0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id= "15_nwl"><スパン スタイル="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">頭スパン>a>< ;/スパン>>
-
<ボディ>
-
ボディ>
-
html>
Chrome で fibonacci.html を開き、制御台が次のように出力されました:
開始計算: 40 時間:1316508212705
私は計算数列の時間:1316508212734
定時器
XML/HTML コード复制コンテンツ到剪贴板
-
<スパン スタイル="width: auto; height : auto; float: none;" id="9_nwp"> ><a スタイル="text-decoration: none;" mpid="9" ターゲット=" _blank" href="http://m.sbmmt.com/cpro/ui/uijs.php?adclass=0&app_id =0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=����&k0=����&kdi0=0&luki=2&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=45fdcf1 cab219561&ssp2=1&stid=0&t =tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id=" 9_nwl"><スパン スタイル="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">関数数 スパン>a>スパン>
計算数列で実行完了時間:1316508213735
結果:102334155 時間:1316508262820 使用時間:50115
この例は、ワーカーで実行されるフィボナッチ数列の計算を示しており、メイン プロセスの実行には影響せず、完全に独立したオンライン プロセスで計算され、計算の完了後にのみ結果が送信されます。
Web ワーカーを利用することで、フロントエンドでいくつかの複雑な大量の計算を実行することができますが、トップページの表示に影響を与えることはなく、また、画面に忙しいことを示すこともありません。
次のこの例では、Web ワーカーを使用してフィールド内のピクセルを計算します。フィールドの開始時は 1 枚ずつ作成され、ワーカーは 1 つのピクセル値のみを計算します。
http://nerget.com/rayjs-mt/rayjs.html
三:労働者のその他尝试
私は URL を受信してワーカーを構築します、那么我们は Web ワーカーを利用していくつかの類似の jsonp の要求を実行できるかどうか、大家知道 jsonp はスクリプト标签を介して json データをダウンロードしています、script 元素は Web ワーカーがインストールを実行できる場合は、アップロードと実行の両方が妨げられます。
以下のこの例は、Web Worker、jsonp、ajax の 3 つの異なる方法で 169.42KB の JSON データを追加します
JavaScript コード
复制コンテンツ到剪贴板
-
-
関数 $E(id) {
-
return document.getElementById(id);
- }
-
onload =関数() {
-
-
$E('workerLoad').onclick =function() {
-
var url ='http://js.wcdn.cn/aj/mblog/face2' ;
-
var d = (new Date()).valueOf();
-
var worker =new Worker(url);
-
worker.onmessage =関数(obj) {
-
console.log('ウェブ ワーカー: ' ((new Date()).valueOf() - d));
- };
- };
-
-
$E('jsonpLoad').onclick =function() {
-
var url ='http://js.wcdn.cn/aj/mblog/face1' ;
-
var d = (new Date()).valueOf();
- STK.core.io.scriptLoader({
-
メソッド:「投稿」、
- url : url,
-
onComplete : 関数() {
-
console.log('jsonp: ' ((new Date()).valueOf() - d));
- }
- });
- };
-
-
$E('ajaxLoad').onclick =function() {
-
var url ='http://js.wcdn.cn/aj/mblog/face' ;
-
var d = (new Date()).valueOf();
- STK.core.io.ajax({
- url : url,
-
onComplete : 関数(json) {
-
console.log('ajax: ' ((new Date()).valueOf() - d));
- }
- });
- };
- };
HTML页面:/aj/webWorker/worker.html
XML/HTML コード复制コンテンツ到剪贴板
- >
- <html>
-
<<スパン スタイル="width: auto; height: auto; float: none;" id="4_nwp"><a スタイル="text-装飾: なし;" mpid="4" ターゲット ="_blank" href="http://m.sbmmt.com/ cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=head&k0=head&kdi0=0&luki=6&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1 &seller_id=1&sid=45fdcf1cab219561&ssp2= 1&stid=0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id="4_nwl"><スパン スタイル="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">頭 スパン>a>< /スパン>>
-
<メタ http-equiv=" Content-Type" content="text/html; charset=utf-8"/>
- <title>ワーカーの例: load < スパン スタイル="width: auto; height: auto; float: none;" id="5_nwp"><a style="text-decoration: none;" mpid= "5" ターゲット="_blank" href="http://m.sbmmt.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk =619521ab1ccffd45&k=data&k0=data&kdi0=0&luki=4&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=45fdcf1cab219561&ssp2=1&stid=0&t=tpclicked3_hc&tu=u1922 429&u=http://www.admin10000.com/document/1183.html&urlid=0 " id="5_nwl"><スパン スタイル="color:#0000ff;font-size:14px;width:auto;height:auto;float :none;">データスパン>< ;/a>スパン> タイトル>
- <script src="http: //js.t.sinajs.cn/STK/js/gaea.1.14.js" type="text/< ;スパン style="幅: auto; 高さ: 自動; float: none;" id="6_nwp">< a style="text-decoration: none;" mpid="6" ターゲット="_blank" href="http://m.sbmmt.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di= 128&fv=0&is_app=0&jk=619521ab1ccffd45&k=javascript&k0=javascript&kdi0=0&luki=9&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=45fdcf1cab219561&ssp2=1&stid=0& t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/ 1183.html&urlid=0" id="6_nwl">< ;スパン スタイル="color:#0000ff;font-size:14px;width:auto;高さ:自動;浮動小数点:なし;">javascriptスパン>a>スパン>">スクリプト>
- <スクリプト type="text/ javascript" src="http://js.wcdn.cn/aj/webWorker/core.js" >>スクリプト>
-
頭>
-
<ボディ>
-
<入力 タイプ="ボタン" id="workerLoad" value="web worker追加ダウンロード">input>
-
<入力 タイプ="ボタン" id="jsonpLoad" value="jsonp加ダウンロード">input>
-
<入力 タイプ="ボタン" id="<スパン style="幅: 自動; 高さ: 自動; float: none;" id="7_nwp">< a style="text-decoration: none;" mpid="7" ターゲット="_blank" href="http://m.sbmmt.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di= 128&fv=0&is_app=0&jk=619521ab1ccffd45&k=ajax&k0=ajax&kdi0=0&luki=8&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=45fdcf1cab219561&ssp2=1&stid =0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/ 1183.html&urlid=0" id="7_nwl">< ;スパン スタイル="color:#0000ff;font-size:14px;width:auto; height:auto;float:none;">ajaxspan>a>スパン>Load" value="ajax 追加ダウンロード">入力>
-
ボディ>
-
html>
設置HOST
127.0.0.1 js .wcdn.cn
http://js.wcdn.cn/aj/webWorker/worker.html 访问页面然后分别通过三种方式加下データデータ,到制台输出:
web ワーカー: 174
jsonp: 25
ajax: 38
多試幾次發現透過jsonp和ajax載入資料的時間相差不大,而web worker的載入時間一直處於高位,所以用web worker來載入資料還是比較慢的,即便是大數據量情況下也沒任何優勢,可能是Worker初始化新起執行緒比較耗時間。除了在加載過程中是無阻塞的之外沒有任何優勢。
那麼web worker是否能支援跨域js載入呢,這次我們透過http://127.0.0.1/aj/webWorker/worker.html 來存取頁面,當點擊」web worker載入」載入按鈕時Chrome下無任何反映,FF6下提示錯誤。由此我們可以知道web worker是不支援跨網域載入JS的,這對於將靜態檔案部署到單獨的靜態伺服器的網站來說是個壞消息。
所以web worker只能用來載入同域下的json數據,而這方面ajax已經可以做到了,而且效率更高更通用。還是讓Worker做它自己擅長的事吧。
四:總結
web worker看起來很美好,但處處是魔鬼。
我們可以做什麼:
1.可以載入一個JS進行大量的複雜計算而不掛起主進程,並透過postMessage,onmessage進行通訊
2.可以在worker中透過importScripts(url)載入另外的腳本檔
3.可以使用 setTimeout(), clearTimeout(), setInterval(), and clearInterval()
4.可以使用XMLHttpRequest來傳送請求
5.可以存取navigator的部分屬性
有那些限制:
1.不能跨域載入JS
2.worker內程式碼不能存取DOM
3.各個瀏覽器對Worker的實現不大一致,例如FF裡允許worker中創建新的worker,而Chrome中就不行
4.不是每個瀏覽器都支援這個新特性