cloudpack あら便利カレンダー 2017 16日目の記事です。
JavaScriptには非同期処理やイベント発火で実行されるもの、またWeb Workersを利用した別スレッドでの実行など記述した順序どおりではない実行タイミングのものがわりと多用されます。
そこでふと気になったのでそれぞれの実行順序ってどうなっているのか
Web Workersの別スレッドで実行された結果がどのタイミングで受取ったイベント発行されるのか気になったので
サンプルのコードを書いてざっくり調査してみました。
実行される処理
- Web Worker1での1つめの処理
- Web Worker2で2つめのループ処理
- Web Worker1で3つめのループ処理
- 非同期で実行される処理(setTimeout)
- べた書きでのループ処理1
- べた書きでのループ処理2
- ボタンクリックでのイベント発火
記述した順序は上に書いたとおりで試しています。
書いたコード
// メインのスクリプト document.getElementById('btn') .addEventListener('click', () => console.info('button click fired!!!')); document.getElementById('start') .addEventListener('click', () => { workerLog = function (e) { console.group(); console.log(`%c${e.data} Worker onmessage fired!!!`, 'background: yellow; color:blue;'); } let myWordker = new Worker('./worker.js'); myWordker.onmessage = workerLog let myWordker2 = new Worker('./worker.js'); myWordker2.onmessage = workerLog myWordker.postMessage("First Worker>>>"); myWordker2.postMessage("Second Worker>>>"); myWordker.postMessage("Third Worker>>>"); setTimeout(() => { console.groupCollapsed(); for (let i = 0; i < 10000; i++) { console.log('First Timeout>>>' + i); } console.groupEnd(); }, 10) console.groupCollapsed(); for (let i = 0; i < 10000; i++) { console.log('First Loop>>>' + i); } console.groupEnd(); console.groupCollapsed(); for (let i = 0; i < 10000; i++) { console.log('Second Loop>>>' + i); } console.groupEnd(); })
// Worker onmessage = function(e) { let ar = [] // console.group(); for(let i=0; i<10; i++) { ar.push(i) // console.log(e.data+i) } postMessage(e.data) }
結果
べた書きで書いたループ処理の実行が2つとも完了しない限り、
Workerからのメッセージ受取イベントonmessage
や、 非同期処理setTimeout
の実行は開始されませんでした。
またループ処理の途中で割り込み処理が入ることはないです。
クリックイベントに関してはメインのスレッドが完了後、イベントの発火が登録されていればsetTimeout
やonmessage
の処理よりも先に実行されました。
以下にサンプルコードをアップしています。
https://nobu222.github.io/WebWorker-sample/