Web ワーカーを使用できます。ここでの古い回答のいくつかは、広くサポートされていないと言っています (これらの回答が書かれたときではなかったと思います) が、今日ではすべての主要なブラウザーでサポートされています。
Web ワーカーを実行するには、組み込みWorker
クラスのインスタンスを作成する必要があります。コンストラクターは、バックグラウンドで実行するコードを含む JavaScript ファイルの URI である 1 つの引数を取ります。例えば:
let worker = new Worker("/path/to/script.js");
Web ワーカーは同一オリジン ポリシーの対象となるため、このようなパスを渡す場合、ターゲット スクリプトはそれを呼び出すページと同じドメインにある必要があります。
このためだけに新しい Javascript ファイルを作成したくない場合は、データ URI を使用することもできます。
let worker = new Worker(
`data:text/javascript,
//Enter Javascript code here
`
);
オリジン ポリシーが同じであるため、データ URI から AJAX 要求を送信することはできません。そのため、Web ワーカーで AJAX 要求を送信する必要がある場合は、別の Javascript ファイルを使用する必要があります。
指定したコード (別のファイルまたはデータ URI のいずれか) は、Worker
コンストラクターを呼び出すとすぐに実行されます。
残念ながら、Web ワーカーは外部の Javascript 変数、関数、クラス、DOM のいずれにもアクセスできませんが、postMessage
メソッドとonmessage
イベントを使用することでこれを回避できます。外側のコードでは、これらは worker オブジェクト (worker
上記の例) のメンバーであり、worker の内側では、これらはグローバル コンテキストのメンバーです (したがってthis
、前に何もない を使用するか、そのように呼び出すことができます)。
postMessage
onmessage
両方の方法で動作するため、がworker.postMessage
外部コードで呼び出されるonmessage
とワーカーで起動され、ワーカーでpostMessage
が呼び出されるとworker.onmessage
外部コードで起動されます。
postMessage
これは、渡したい変数です (ただし、配列を渡すことで複数の変数を渡すことができます)。残念ながら、関数と DOM 要素を渡すことはできません。オブジェクトを渡そうとすると、メソッドではなく属性のみが渡されます。
onmessage
オブジェクトである 1 つの引数を取りMessageEvent
ます。MessageEvent
オブジェクトには、のdata
最初の引数を使用して送信されたデータを含む属性がありますpostMessage
。
これは、Web ワーカーを使用した例です。この例では、functionThatTakesLongTime
1 つの引数を取り、その引数に応じて値を返す関数 がfunctionThatTakesLongTime(foo)
あり、UI をフリーズせずに検索するために Web ワーカーを使用したいと考えてfoo
います。外部コード内の変数はどこにありますか。
let worker = new Worker(
`data:text/javascript,
function functionThatTakesLongTime(someArgument){
//There are obviously faster ways to do this, I made this function slow on purpose just for the example.
for(let i = 0; i < 1000000000; i++){
someArgument++;
}
return someArgument;
}
onmessage = function(event){ //This will be called when worker.postMessage is called in the outside code.
let foo = event.data; //Get the argument that was passed from the outside code, in this case foo.
let result = functionThatTakesLongTime(foo); //Find the result. This will take long time but it doesn't matter since it's called in the worker.
postMessage(result); //Send the result to the outside code.
};
`
);
worker.onmessage = function(event){ //Get the result from the worker. This code will be called when postMessage is called in the worker.
alert("The result is " + event.data);
}
worker.postMessage(foo); //Send foo to the worker (here foo is just some variable that was defined somewhere previously).