私は疑問に思っています-JavaScriptでマルチスレッドを他にどのように達成できますか?他の重要な方法はありますか?
コードを、明示的なループや直接の関数呼び出しを持たないJavaScriptコードに変換することができます。代わりに、コードはスレッドエンジンによって管理される小さな実行単位に分割されます。私のサンプルコードでは、ループのある関数がどのように変換されるかを示していますが、例を単純にするために、関数呼び出しのメカニズムを省略しています。
変換のプロセスは、基本的に分割ポイントでコードを分割することによって機能します。これらの除算ポイントは、関数呼び出しとループです(上記のとおり)。この例では、オブジェクトとキーを使用しましたが、ユニットがスタックをオブジェクト変数として格納した場合(つまり、this.foo = bar
の代わりにを使用して格納した場合)、ブラウザーのJavaScriptエンジンではるかに簡単になる可能性がありますstack["foo"] = bar
。
たとえば、次のコード:
// Phoney method purely to demonstrate structure
function Foo() {
var i,
sum = 0,
accumulator_list = [],
accumulator_modulus = [],
kMaxAccumulatorCount = 100;
// Calculate accumulations
for(i = 0; i < kMaxAccumulatorCount; ++i) {
current_accumulator = GetNextAccumulator()
accumulator_list[i] = current_accumulator;
sum = sum + current_accumulator;
}
// Calculate accumulator modulus
for(i = 0; i < kMaxAccumulatorCount; ++i) {
current_accumulator = accumulator_list[i];
accumulator_modulus[i] = current_accumulator % kMaxAccumulatorCount;
}
}
...このようなものに:
function Foo_A(caller,stack) {
var stack = {};
stack["i"] = undefined;
stack["sum"] = 0;
stack["accumulator_list"] = [];
stack["accumulator_modulus"] = [];
stack["kMaxAccumulatorCount"] = 100;
stack["i"] = 0;
return {caller: caller, stack: stack, next=Foo_B};
}
function Foo_B(caller, stack) {
stack["current_accumulator"] = GetNextAccumulator();
stack["accumulator_list"][stack["i"]] = stack["current_accumulator"];
stack["sum"] = stack["sum"] + stack["current_accumulator"];
// For-loop condition satisfied ?
if(stack["i"] < stack["kMaxAccumulatorCount"]) {
++stack["i"];
return {caller: caller, stack: stack, next:Foo_B};
} else {
// Initialise the next for loop.
stack["i"] = 0;
return {caller: caller, stack: stack, next:Foo_C};
}
}
function Foo_C(caller, stack) {
stack["current_accumulator"] = stack["current_accumulator"][stack["i"]];
stack["accumulator_modulus"][stack["i"]] = stack["current_accumulator"] % stack["kMaxAccumulatorCount"];
// For-loop condition satisfied ?
if(stack["i"] < stack["kMaxAccumulatorCount"]) {
++stack["i"];
return {caller: caller, stack: stack, next:Foo_C};
} else {
// Function has finished so the next will be null. When the thread-engine sees this it simulates the behaviour of a return, pops its virtual stack and returns execution to the caller
return {caller: caller, stack: stack, next:null};
}
}