Come implementare una chiusura in JavaScript

Come potrebbe essere implementato in JavaScript JavaScript equivalente a lock in C #?

Quindi, per spiegare quello che sto pensando un semplice caso d'uso è:

L'utente fa clic sul button B B solleva un evento onclick. Se B è in event-state evento, l'evento attende che B sia ready-state prima di propagare. Se B è ready-state , B è bloccato ed è impostato event-state , quindi l'evento si propaga. Quando la propagazione dell'evento è completata, B è impostata ready-state .

Ho potuto vedere come qualcosa vicino a questo potrebbe essere fatto, semplicemente aggiungendo e rimuovendo il ready-state class dal button. Tuttavia, il problema è che un utente può fare clic su un button due volte di seguito più velocemente della variabile che può essere impostato, quindi questo tentativo di block non funziona in alcune circostanze.

Qualcuno sa come implementare una serratura che non riesce a funzionare in JavaScript?

La serratura è un'idea discutibile in JS che è destinata ad essere senza filo e senza bisogno di protezione concorrenziale. Stai cercando di combinare le chiamate su un'operazione differita. Il model che segue per questo è l'utilizzo di callback. Qualcosa come questo:

 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); } }); } } 

Puoi anche implementarlo utilizzando gli ascoltatori di events DOM o una soluzione pubsub.

JavaScript è, con poche eccezioni ( XMLHttpRequest onreadystatechange gestori in alcune versioni di Firefox) event-loop concorrenti . Quindi non dovrai preoccuparti di bloccare in questo caso.

JavaScript ha un model di concorrenza basato su un "ciclo di events". Questo model è piuttosto diverso dal model in altre lingue come C o Java.

Un runtime di JavaScript contiene una coda di messaggi, che è un elenco di messaggi da elaborare. A ciascun messaggio è associata una function. Quando la pila è vuota, un messaggio viene eliminato dalla coda e elaborato. L'elaborazione consiste nel call la function associata (creando così un frame iniziale) L'elaborazione dei messaggi finisce quando la pila diventa vuota.

Ogni messaggio viene elaborato completamente prima di elaborare qualsiasi altro messaggio. Ciò offre alcune belle properties; quando si giustifica il tuo programma, incluso il fatto che each volta che una function viene eseguita, non può essere pre-empted ed eseguirà completamente prima di eseguire qualsiasi altro codice (e può modificare i dati che la function manipola). Ciò differisce da C, per esempio, where se una function viene eseguita in un thread, può essere fermata in qualsiasi punto per eseguire un altro codice in un altro thread.

Un aspetto negativo di questo model è che se un messaggio richiede troppo tempo per completare, l'applicazione web non è in grado di elaborare interazioni utente come fare clic o scorrere. Il browser lo attenua con la window di dialogo "Uno script sta prendendo troppo tempo per eseguire". Una buona pratica da seguire è di rendere l'elaborazione dei messaggi corti e, se ansible, tagliare un messaggio in più messaggi.

Per ulteriori link sulla concorrenza degli events, consultare E

Le serrature sono un concetto richiesto in un sistema multi-filettato. Anche con i thread del lavoratore, i messaggi vengono inviati per valore tra i lavoratori in modo che il block non sia necessario.

Sospetto che sia necessario impostare un semaforo (sistema di logging) tra i pulsanti.

Perché non distriggersre il button e abilitarlo dopo aver terminato l'evento?

 <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> 

Buon codice !!!

Ho avuto successo promemory mutex .

Sono d'accordo con altre risposte che potrebbe non essere necessario bloccare nel tuo caso. Ma non è vero che non si ha mai bisogno di bloccare Javascript. È necessario un'esclusività reciproca quando si accede a risorse esterne che non gestiscono la concorrenza.

Alcune aggiunte alla risposta di JoshRiver secondo il mio caso;

 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); }); 

Ci sarà solo una chiamata api e queste due funzioni consumeranno lo stesso risultato.