昨年、いくつかのプロジェクトがJavaScriptを使用してロックする必要があるため、いくつかの同様のプロジェクトを書きました。
次のようにコードコードをコピーします。
// Indream Luoが発行
// contal:[email protected]
//バージョン:中国語1.0.0
!
window.indream = windom.indream ||。
$ .indream = indream;
indream.async = {
//
//ロック
//ロック:ロックの数
//アクション:ロック解除後の実行方法
//
ロック:function(lock、action){
$ .indream.async.waitings [lock] = $ .indream.async.waitings [lock] ||
$ .indream.async.waitings [lock] .push(action);
//ロックが使用されていない場合、現在のアクションがロックをブロックします
if(!$。indream.async.lockstatus [lock] && action){
$ .indream.async.lockstatus [lock] = true;
if(arguments.length> 2){{
var args = 'arguments [2]';
for(var i = 3; i <arguments.length; i ++){
args + = '、arguments [' + i + ']';
}
eval( '$。indream.async.action.call(action、' + args + ')');
} それ以外 {
$ .indream.async.action.call(action);
}
}
}、
//
//ロック解除
//ロック:ロックの数
//
ReleseLock:function(lock){
$ .indream.async.waitings [lock] .shift();
//待機キューがオブジェクトである場合、待機キューが実行され、それ以外の場合はロックを解除します
if($ .indream.async.waitings [lock] .length){
$ .indream.async.waitings [lock] [0]();
} それ以外 {
$ .indream.async.lockstatus [lock] = false;
}
}、
//
//ステータスをロックします
//
lockstatus:[]、
//
//イベントが完了するのを待っています
//ロック:ロックコーディング、同じエンコードがシーケンスに統合され、トリガーがトリガーされます
//
待機:function(lock、action){
$ .indream.async.waitings [code] = $ .indream.async.waitings [code] ||
$ .indream.async.waitings [code] .push(action);
}、
//
//シーケンスを待っています
//
待機:[]、
//
//データキャッシュ
//
アクション: {
//
//監視およびコールバックの関連方法
//
折り返し電話: {
//
//モニター
//
聞く:function(actionname、callback){
var list = $ .indream.async.action.calllback.list;
list [actionname] = list [actionname] ||。
list [actionname] .push(callback);
}、
//
//
//
call:function(actionname、args){
var list = $ .indream.async.action.calllback.list;
if(list [actionname] && list [actionname] .length){
for(var i in list [actionname]){
$ .indream.async.action.call(list [ActivityName] [i]、args);
}
}
}、
//
//既存のコールバックリスト
//
リスト:[]
}、
//
//メソッドが存在するかどうか、および適切な実行方法を選択するためにパラメーターが存在するかどうか
//
呼び出し:function(action){
if(action){
if(arguments.length> 1){{
var args = 'arguments [1]';
for(var i = 2; i <arguments.length; i ++){
args + = '、arguments [' + i + ']';
}
eval( 'action(' + args + ')');
} それ以外 {
アクション ();
}
}
}
}
}
}(window.jquery);
相互ロックのいくつかの要素は次のとおりです。
•ロックしてロック解除します
•キューを待っています
•実行方法
上記のロックの使用:
次のようにコードコードをコピーします。
//ロックの名前を定義します
var lock = 'scrolltop()';
//ロックを使用します
$ .indream.async.lock(lock、function(){{){
var scrolltop = $(window);
varタイマー;
varfulltime = 100;
for(タイマー= 0;タイマー<=フルタイム;タイマー += 10){
setimeout( '$(window)。scrolltop(' +(scrolltop *(fulltime -timer) / fulltime) + ');'、タイマー);
}
//ロックを解放します
Settimeout( '$。Indream.async.releaselock( "' + lock + '");'、fulltime);
});
この時間の実現については、簡単に説明してください。
- スピンロックまたは信号量
JavaScriptにはロック機能がないため、ロックは高レベルで実装されます。
JavaScript Single -Threadの原則によれば、JSのスレッドリソースは非常に限られており、スピンロックの使用には適していないため、セマフォを使用することを選択しました。
セルフスピンロックは大まかにこのようなものです。もちろん、より便利です。
次のようにコードコードをコピーします。
while(true){
//何かをする...
}
これは必然的に完全なスレッドを利用する必要があります。残念ながら、JSには実行に使用できるスレッドが1つしかありません。もちろん、必要に応じて、setintervalとclearintervalの組み合わせを選択してそれを実現できます。効果は良好になります。
ここでは、信号量の方法は単純で、原則はコードと同じくらい簡単です。仕事の順序は大まかです:
•コードセグメント(コールバックアクション)を待機キューに押し込みます
•現在のロックが保持されているかどうかを判断します。
•ロックが解放されると、次の調整が待機キューに渡され、ロックが渡されて実行されます
- 自動リリースまたは手動リリース
最も快適な方法は、もちろん、現在のプログラムが実行されたときに自動的にリリースされることですが、シーンのリリースをカスタマイズする必要があるため、これは簡単ではありません。
それ自体で使用されるのは非同期的な方法であるため、AjaxやjQueryアニメーションなど、他の非同期内容物が通常表示されます。現時点では、自動リリースは需要を満たしていません。実際、実際の「実行」は、その中の非同期コールバックの後、つまり基本的に開発者だけが自分自身を把握できるため、ここでリリースすることを選択するためです。
ただし、欠陥、つまり繰り返しリリースされています。
すべてのロックオブジェクトは公開されていること、またはローカル変数がアクセスレベルで分離されていない限り、JSのすべてのオブジェクトが公開されていることがわかります。ただし、「ロック」自体は公共のリソースであるため、対処する方法はありません。
ここで行うことができる最適化は、SetIntervalやClearIntervalのような公開ロック名のロックである必要があり、プライベートロックIDでロック解除すると、繰り返しリリースを防ぐことができます。ただし、上記の古いコードにはありませんが、すぐに使用されると推定されています。