L'année dernière, plusieurs projets devaient utiliser JavaScript pour verrouiller, alors j'en ai écrit quelques similaires, dont l'un:
Copier le code du code comme suit:
// Publié par INDREAM LUO
// contal: [email protected]
// Version: chinois 1.0.0
! Fonction ($) {
Window.Indream = Window.Indream || {};
$ .Indream = INDREAM;
indream.async = {
//
//Verrouillage
// verrouillage: le nombre de verrous
// Action: la façon d'exécuter après le déverrouillage
//
Lock: fonction (verrouillage, action) {
$ .Indream.async.Waitings [Lock] = $ .Indream.Async.Waittings [Lock] || [];
$ .Indream.async.Waitings [Lock] .push (action);
// Si le verrou n'est pas utilisé, l'action actuelle bloque le verrouillage
if (! $. Indream.async.lockStatus [Lock] && action) {
$ .indream.async.lockStatus [Lock] = true;
if (arguments.length> 2) {{{
var args = 'arguments [2]';
pour (var i = 3; i <arguments.length; i ++) {
args + = ', arguments [' + i + ']';
}
Eval ('$. IndReam.Async.Action.Call (Action,' + Args + ')');
} Autre {
$ .Indream.async.Action.Call (Action);
}
}
},
//
// déverrouiller
// verrouillage: le nombre de verrous
//
Releaselock: fonction (verrouillage) {
$ .Indream.async.Waitings [Lock] .Shift ();
// Si la file d'attente d'attente est un objet, la file d'attente d'attente est exécutée, sinon déverrouiller
if ($ .indream.async.waitings [Lock] .length) {
$ .Indream.async.Waitings [Lock] [0] ();
} Autre {
$ .indream.async.lockStatus [Lock] = False;
}
},
//
// Statut de verrouillage
//
Lockstatus: [],
//
// en attente de la fin de l'événement
// verrouillage: codage de verrouillage, le même codage sera intégré dans une séquence, déclenchant
//
Attendre: fonction (verrouillage, action) {
$ .Indream.async.Waitings [Code] = $ .Indream.Async.Waitings [Code] || [];
$ .Indream.async.Waitings [code] .push (action);
},
//
// en attente de la séquence
//
attend: [],
//
// Cache de données
//
ACTION: {
//
// Méthodes connexes pour la surveillance et le rappel
//
rappel: {
//
//moniteur
//
Écouter: function (actionName, rappel) {
var list = $ .indream.async.action.calllback.list;
list [actionName] = list [actionName] || [];
list [actionName] .push (rappel);
},
//
//
//
Appel: fonction (ActionName, args) {
var list = $ .indream.async.action.calllback.list;
if (list [actionName] && list [actionName] .length) {
pour (var i dans list [actionName]) {
$ .Indream.async.Action.Call (list [ActivityName] [i], args);
}
}
},
//
// la liste de rappel existante
//
Liste: []
},
//
// si la méthode existe et si le paramètre existe pour choisir la méthode d'exécution appropriée
//
Appel: fonction (action) {
if (action) {
if (arguments.length> 1) {{
var args = 'arguments [1]';
pour (var i = 2; i <arguments.length; i ++) {
args + = ', arguments [' + i + ']';
}
Eval ('action (' + args + ')');
} Autre {
action ();
}
}
}
}
}
} (window.jquery);
Plusieurs éléments de verrouillage mutuel sont:
• verrouiller et déverrouiller
• En attente de la file d'attente
• Méthode d'exécution
Utilisation des verrous ci-dessus:
Copier le code du code comme suit:
// définit le nom du verrouillage
var lock = 'scrolltop ()';
// utilise le verrouillage
$ .indream.async.lock (Lock, function () {{) {
var scrolltop = $ (fenêtre).
var temporisateur;
Varfulltime = 100;
pour (temporisateur = 0; temporisateur <= temps plein; temporisateur + = 10) {
setTimeout ('$ (fenêtre). ScrollTop (' + (ScrollTop * (Fulltime -timer) / Fulltime) + ');', Timer);
}
// Libérez le verrouillage
setTimeout ('$. IndReam.Async.releSelock ("' + Lock + '");', à temps plein);
});
En ce qui concerne la réalisation de cette époque, expliquez brièvement.
-Le verrouillage de rotation ou montant du signal
JavaScript n'a pas de fonction de verrouillage, donc les verrous sont implémentés à des niveaux élevés.
Selon le principe du single-thread javascript, les ressources de thread de JS sont très limitées et ne conviennent pas à l'utilisation de verrous de spin, j'ai donc choisi d'utiliser le sémaphore.
Le verrouillage de l'auto-spin est à peu près comme ça, bien sûr, à faire tandis que c'est plus utile:
Copier le code du code comme suit:
While (true) {
// faire quelque chose ...
}
Cela doit inévitablement profiter du fil complet. Bien sûr, si nécessaire, vous pouvez choisir la combinaison de SetInterval et ClearInterval pour y parvenir, et l'effet sera bon.
La méthode du montant du signal est simple ici, et le principe est simple, tout aussi court que le code. L'ordre de travail est à peu près:
• Poussez le segment de code (l'action de rappel) dans la file d'attente d'attente
• Déterminez si le verrouillage actuel est maintenu.
• Lorsque le verrouillage est libéré, le prochain ajustement est passé dans la file d'attente d'attente, et le verrou est passé et exécuté
-Dans la version automatique ou la version manuelle
Le moyen le plus confortable est, bien sûr, il est automatiquement publié lorsque le programme actuel est exécuté, mais ce n'est pas facile, car davantage de situations doivent personnaliser la version de la scène.
Ce qui est utilisé en soi est la méthode asynchrone, donc d'autres contenus asynchrones apparaissent généralement, comme l'animation Ajax et JQuery. À l'heure actuelle, la version automatique ne répond pas à la demande, car en fait, la véritable "exécution" est qu'après le rappel asynchrone, c'est-à-dire que seuls les développeurs peuvent saisir eux-mêmes, afin qu'ils choisissent de le libérer ici.
Cependant, il y a encore des défauts, c'est-à-dire une libération répétée.
On peut voir que tous les objets de verrouillage sont publics, ou que tous les objets de JS sont publics, à moins que la variable locale ne soit isolée au niveau d'accès. Cependant, le "verrouillage" lui-même est une ressource publique, il n'y a donc aucun moyen de y faire face.
L'optimisation qui peut être effectuée ici doit être des verrous avec un nom de verrouillage public comme SetInterval et ClearInterval, et déverrouiller avec des ID de verrouillage privés peut empêcher la libération répétée. Cependant, il n'y a pas dans l'ancien code ci-dessus, on estime qu'il sera bientôt utilisé.