まず、JavaScriptは完全にシングルスレッドであることに言及することが重要です。マルチスレッドをエミュレートすることは、実際には道のりではありません。イベントループに依存する方がはるかに良いでしょう。
前述のように、Webワーカーを使用することはできますが、実際にはブラウザー間のコンプライアンスがないため、Webワーカーは無視します。また、WebワーカーでDOM操作を行うことはできません。
node.jsを見て、イベントループがマルチスレッドの優れた代替手段である理由の背後にある推論を見てみましょう。彼は、なぜそれがこのビデオの良い選択肢であるのかについて非常にうまく触れていると思います。
したがって、関数の配列を作成してそれらを反復処理するのではなく、代わりにイベントを作成し、一連の関数をそれらにバインドして、そのイベントをトリガーすることができます。イベントの非常に軽量な実装は、backbone.jsにあります。
JavaScriptではスレッドが1つしかないため、スレッドを一時停止することはできません。関数にポイントが含まれていないと、関数を一時停止または再開する方法はありません。
これをエミュレートする方法は1つだけです。うまく構築されたJavaScriptを分解し、JavaScriptを一時停止および再開できるシステムを構築するJavaScriptパーサーを作成します。
この関数を例にとってみましょう
function(i) {
j = i + 1;
console.log(j);
return foo(j);
}
そしてそれをこれに変換します
var bar = function(i) {
var r = {};
var j = i + 1;
var f = function() {
console.log(j);
var g = function() {
return foo(j);
};
onNext(g, arguments.callee, this, r);
};
onNext(f, arguments.callee, this);
return r;
}
とで関数を拡張する必要があり.suspend
ます.resume
Function.prototype.suspend = function() {
this.__suspended = true;
}
Function.prototype.resume = function() {
this.__suspended = false;
}
function onNext(callback, function, context, returnObj) {
if (!function.__suspended) {
var cb = function() {
Backbone.Events.unbind("run", cb);
returnObj.r = callback.call(this);
}
Backbone.Events.bind("run", cb);
}
}
setInterval(function() {
Backbone.Events.trigger("run");
}, 5);
また、へのすべての参照をに置き換える必要がありvar a = b()
ます
callFunctionAsync(b, context, args, function(return) {
var a = return;
...
});
私はあなたに憤慨を任せます。今のところ、すべての関数はオブジェクトを返し、が値に設定されているr
場合にのみオブジェクトr.r
が「返されます」。r.r
したがって、が設定されているかどうか、および関数asyncコールバックがトリガーされているかどうかを確認して、イベントループがまだ「戻っている」かどうかを確認してください。
ねえ、私たちが持っているものを見てください。イベントループの周りでスレッドを実行することにより、スレッドをエミュレートしていました。スレッドをエミュレートするよりも、コードでイベントループをネイティブに使用する方がはるかに優れています。
基本的に、イベントループを再度実行するときに、関数にコードの次の行を実行させる。また、イベントループを一周するときに、特定の「機能」が一時停止または再開されているかどうかを確認します。
簡潔にするために、関数を「関数」に戻すバブリングは実装していません。これをエミュレートするのはそれほど難しいことではありません。
イベントループを直接使用するか、偽のスレッドメソッドを使用して、コードをコンパイルするときに恐ろしく見えないようにコンパイラにコードをコンパイルしてもらいます。
あなたがデッドロックを引き起こした場合、あなたに幸運を祈ります。