Letztes Jahr mussten mehrere Projekte JavaScript zum Sperren verwenden, also habe ich ein paar ähnliche geschrieben, von denen eines:
Kopieren Sie den Code -Code wie folgt:
// veröffentlicht von Indream Luo
// Contal: [email protected]
// Version: Chinese 1.0.0
! Funktion ($) {
window.indream = window.indream || {};
$ .Indream = Indream;
Indream.async = {
//
//Sperren
// Sperre: Die Anzahl der Sperre
// Aktion: Die Art und Weise, nach dem Entsperren auszuführen
//
Sperre: Funktion (Sperre, Aktion) {
$ .indream.async.waitings [lock] = $ .indream.async.waitings [lock] || [];
$ .indream.async.waitings [lock] .push (action);
// Wenn das Schloss nicht verwendet wird, blockiert die aktuelle Aktion das Schloss
if (! $. indream.async.lockstatus [lock] && action) {
$ .indream.async.lockstatus [lock] = true;
if (argumente.length> 2) {{{{{{{{{{{{{{{{{{
var args = 'Argumente [2]';
für (var i = 3; i <argumente.length; i ++) {
args + = ', Argumente [' + i + ']';
}
Eval ('$. Indream.async.Action.call (Aktion,' + args + ')');
} Anders {
$ .indream.async.action.call (action);
}
}
},
//
// Entsperren
// Sperre: Die Anzahl der Sperre
//
Releaselock: function (lock) {
$ .indream.async.waitings [lock] .Shift ();
// Wenn die wartende Warteschlange Objekt ist, wird die wartende Warteschlange ausgeführt, ansonsten entsperren
if ($ .indream.async.waitings [lock] .Length) {
$ .indream.async.waitings [lock] [0] ();
} Anders {
$ .indream.async.lockstatus [lock] = false;
}
},
//
// Status sperren
//
lockstatus: [],
//
// Warten auf die Veranstaltung zu vervollständigen
// Sperre: Sperrencodierung, die gleiche Codierung wird in eine Sequenz integriert, die auslösen
//
Warten Sie: Funktion (Sperre, Aktion) {
$ .indream.async.waitings [Code] = $ .Indream.async.waitings [Code] ||;
$ .indream.async.waitings [Code] .push (Aktion);
},
//
// Warten auf die Sequenz
//
Warten: [],
//
// Datencache
//
AKTION: {
//
// Verwandte Methoden zur Überwachung und Rückrufe
//
Rückruf: {
//
//Monitor
//
Hören Sie: Funktion (ActionName, Callback) {
var list = $ .indream.async.action.calllback.list;
Liste [ActionName] = Liste [ActionName] || [];
Liste [ActionName] .push (Callback);
},
//
//
//
Anruf: Funktion (ActionName, Args) {
var list = $ .indream.async.action.calllback.list;
if (list [actionName] && list [actionName] .length) {
für (var i in list [actionName]) {
$ .indream.async.action.call (list [acityName] [i], args);
}
}
},
//
// Die vorhandene Rückrufliste
//
Liste: []
},
//
// Ob die Methode vorliegt und ob der Parameter vorhanden ist, um die entsprechende Ausführungsmethode auszuwählen
//
Anruf: Funktion (Aktion) {
if (Aktion) {
if (argumente.length> 1) {{{{{{{{{{{{{{{{{{{
var args = 'Argumente [1]';
für (var i = 2; i <argumente.length; i ++) {
args + = ', Argumente [' + i + ']';
}
Eval ('action (' + args + ')');
} Anders {
Aktion ();
}
}
}
}
}
} (window.jQuery);
Mehrere Elemente der gegenseitigen Verriegelung sind:
• Sperren und entsperren
• Warten auf die Warteschlange
• Ausführungsmethode
Verwendung der oben genannten Schlösser:
Kopieren Sie den Code -Code wie folgt:
// Definieren Sie den Namen des Schlosses
var lock = 'scrolltop ()';
// Verwenden Sie das Schloss
$ .indream.async.lock (lock, function () {{) {{
var scrolltop = $ (Fenster).
var Timer;
varfulltime = 100;
für (Timer = 0; Timer <= Vollzeit; Timer += 10) {
setTimeout ('$ (Fenster). scrolltop (' + (scrolltop * (Vollzeit -timer) / Vollzeit) + ');', Timer);
}
// das Schloss loslassen
setTimeout ('$. Indream.async.Releaselock ("' + lock + '");', Vollzeit);
});
In Bezug auf die Verwirklichung dieser Zeit erklären Sie kurz kurz.
-Die Spinsperr- oder Signalmenge
JavaScript hat keine Sperrfunktion, daher werden die Schlösser auf hohen Ebenen implementiert.
Nach dem Prinzip von JavaScript Single -Thread sind die Thread -Ressourcen von JS sehr begrenzt und es ist nicht geeignet, Spin -Schlösser zu verwenden, daher habe ich mich für die Verwendung des Semaphors entschieden.
Das Selbstspin -Schloss ist natürlich ungefähr so, dass es nützlicher ist:
Kopieren Sie den Code -Code wie folgt:
While (wahr) {
// etwas mach ...
}
Dies muss unweigerlich den vollständigen Thread nutzen. Natürlich können Sie bei Bedarf die Kombination von SetInterval und ClearInterval auswählen, um sie zu erreichen, und der Effekt wird gut sein.
Die Methode der Signalmenge ist hier einfach, und das Prinzip ist einfach, genauso kurz wie der Code. Die Reihenfolge der Arbeit ist grob:
• Drücken Sie das Codesegment (die Rückrufaktion) in die wartende Warteschlange
• Stellen Sie fest, ob das aktuelle Schloss gehalten wird.
• Wenn das Schloss veröffentlicht wird
-In automatische Veröffentlichung oder manuelle Veröffentlichung
Der bequemste Weg ist natürlich automatisch, wenn das aktuelle Programm ausgeführt wird, aber dies ist nicht einfach, da mehr Situationen die Veröffentlichung der Szene anpassen müssen.
Was an sich verwendet wird, ist die asynchrone Methode, sodass normalerweise andere asynchrone Inhalte wie Ajax und JQuery -Animation auftreten. Zu diesem Zeitpunkt entspricht die automatische Veröffentlichung nicht die Nachfrage, da die wahre "Ausführung" tatsächlich, dass nach dem asynchronen Rückruf darin, das ist im Grunde genommen nur die Entwickler sich selbst erfassen, sodass sie sie hier freigeben.
Es gibt jedoch immer noch Mängel, dh wiederholte Freisetzung.
Es ist ersichtlich, dass alle Sperrobjekte öffentlich sind oder dass alle Objekte von JS öffentlich sind, es sei denn, die lokale Variable ist auf der Zugangsebene isoliert. Das "Schloss" selbst ist jedoch eine öffentliche Ressource, daher gibt es keine Möglichkeit, damit umzugehen.
Die Optimierung, die hier durchgeführt werden kann, sollte Sperren mit einem öffentlichen Sperrnamen wie SetInterval und ClearInterval sein und mit privaten Sperr -IDs eine wiederholte Freigabe verhindern. Der obige alte Code gibt jedoch keine, es wird geschätzt, dass er bald verwendet wird.