Wie könnte etwas, das lock
C # entspricht, in JavaScript implementiert werden?
Um zu erklären, was ich für einen einfachen Anwendungsfall halte, ist:
Benutzer klickt auf die Schaltfläche B
. B
löst ein Onclick-Ereignis aus. Wenn B
in ist event-state
die Veranstaltung wartet , B
um in ready-state
vor ausbreitet. Wenn B
in ready-state
, B
gesperrt und auf gesetzt ist event-state
, wird das Ereignis weitergegeben. Wenn die Weitergabe des Ereignisses abgeschlossen ist, B
wird auf gesetzt ready-state
.
Ich konnte sehen, wie etwas in der Nähe davon getan werden konnte, indem ich einfach die Klasse hinzufügte und ready-state
von der Schaltfläche entfernte. Das Problem ist jedoch, dass ein Benutzer zweimal hintereinander schneller auf eine Schaltfläche klicken kann, als die Variable festgelegt werden kann, sodass dieser Versuch einer Sperre unter bestimmten Umständen fehlschlägt.
Weiß jemand, wie man eine Sperre implementiert, die in JavaScript nicht fehlschlägt?
quelle
Antworten:
Lock ist eine fragwürdige Idee in JS, die threadlos sein soll und keinen Parallelitätsschutz benötigt. Sie möchten Aufrufe zur verzögerten Ausführung kombinieren. Das Muster, dem ich hier folge, ist die Verwendung von Rückrufen. Etwas wie das:
var functionLock = false; var functionCallbacks = []; var lockingFunction = function (callback) { if (functionLock) { functionCallbacks.push(callback); } else { $.longRunning(function(response) { while(functionCallbacks.length){ var thisCallback = functionCallbacks.pop(); thisCallback(response); } }); } }
Sie können dies auch mit DOM-Ereignis-Listenern oder einer Pubsub-Lösung implementieren.
quelle
JavaScript ist mit wenigen Ausnahmen (
XMLHttpRequest
onreadystatechange
Handler in einigen Versionen von Firefox) gleichzeitig eine Ereignisschleife . In diesem Fall müssen Sie sich also keine Gedanken über das Sperren machen.Weitere Links zur Ereignisschleifen-Parallelität finden Sie unter E.
quelle
Ich hatte Erfolg Mutex-Versprechen .
Ich stimme anderen Antworten zu, dass Sie in Ihrem Fall möglicherweise keine Sperre benötigen. Aber es ist nicht wahr, dass man niemals Javascript sperren muss. Sie benötigen gegenseitige Ausschließlichkeit, wenn Sie auf externe Ressourcen zugreifen, die keine Parallelität verarbeiten.
quelle
Schlösser sind ein Konzept, das in einem Multithread-System erforderlich ist. Selbst bei Worker-Threads werden Nachrichten nach Wert zwischen Workern gesendet, sodass das Sperren nicht erforderlich ist.
Ich vermute, Sie müssen nur ein Semaphor (Markierungssystem) zwischen Ihren Schaltflächen einstellen.
quelle
Warum deaktivierst du die Schaltfläche nicht und aktivierst sie, nachdem du das Ereignis beendet hast?
<input type="button" id="xx" onclick="checkEnableSubmit('true');yourFunction();"> <script type="text/javascript"> function checkEnableSubmit(status) { document.getElementById("xx").disabled = status; } function yourFunction(){ //add your functionality checkEnableSubmit('false'); } </script>
Viel Spaß beim Codieren !!!
quelle
Einige Ergänzungen zu JoshRivers Antwort gemäß meinem Fall;
var functionCallbacks = []; var functionLock = false; var getData = function (url, callback) { if (functionLock) { functionCallbacks.push(callback); } else { functionLock = true; functionCallbacks.push(callback); $.getJSON(url, function (data) { while (functionCallbacks.length) { var thisCallback = functionCallbacks.pop(); thisCallback(data); } functionLock = false; }); } }; // Usage getData("api/orders",function(data){ barChart(data); }); getData("api/orders",function(data){ lineChart(data); });
Es wird nur einen API-Aufruf geben und diese beiden Funktionen verbrauchen das gleiche Ergebnis.
quelle
Sperren werden in JS weiterhin verwendet. Nach meiner Erfahrung musste ich nur Sperren verwenden, um zu verhindern, dass Spam auf Elemente klickt, die AJAX-Aufrufe ausführen. Wenn Sie einen Loader für AJAX-Aufrufe eingerichtet haben, ist dies nicht erforderlich (sowie das Deaktivieren der Schaltfläche nach dem Klicken). Aber so oder so habe ich das zum Sperren verwendet:
var LOCK_INDEX = []; function LockCallback(key, action, manual) { if (LOCK_INDEX[key]) return; LOCK_INDEX[key] = true; action(function () { delete LOCK_INDEX[key] }); if (!manual) delete LOCK_INDEX[key]; }
Verwendung:
Manuelles Entsperren (normalerweise für XHR)
LockCallback('someKey',(delCallback) => { //do stuff delCallback(); //Unlock method }, true)
Automatische Entsperrung
LockCallback('someKey',() => { //do stuff })
quelle
Hier ist ein einfacher Verriegelungsmechanismus, der über das Schließen implementiert wird
const createLock = () => { let lockStatus = false const release = () => { lockStatus = false } const acuire = () => { if (lockStatus == true) return false lockStatus = true return true } return { lockStatus: lockStatus, acuire: acuire, release: release, } } lock = createLock() // create a lock lock.acuire() // acuired a lock if (lock.acuire()){ console.log("Was able to acuire"); } else { console.log("Was not to acuire"); // This will execute } lock.release() // now the lock is released if(lock.acuire()){ console.log("Was able to acuire"); // This will execute } else { console.log("Was not to acuire"); } lock.release() // Hey don't forget to release
quelle