Jak coś odpowiednika lock
w C # można zaimplementować w JavaScript?
Aby więc wyjaśnić, o czym myślę, prosty przypadek użycia to:
Użytkownik klika przycisk B
. B
podnosi zdarzenie onclick. Jeśli B
jest w event-state
oczekiwania wydarzenie dla B
być w ready-state
przed rozmnożeniowego. Jeśli B
jest w ready-state
, B
jest zablokowany i ustawiony na event-state
, to zdarzenie jest propagowane. Gdy propagacja zdarzenia zostanie zakończona, B
jest ustawiona na ready-state
.
Widziałem, jak można zrobić coś podobnego, po prostu dodając i usuwając klasę ready-state
z przycisku. Jednak problem polega na tym, że użytkownik może kliknąć przycisk dwa razy z rzędu szybciej niż można ustawić zmienną, więc ta próba zablokowania w niektórych okolicznościach zakończy się niepowodzeniem.
Czy ktoś wie, jak zaimplementować blokadę, która nie zawiedzie w JavaScript?
źródło
Odpowiedzi:
Lock to wątpliwy pomysł w JS, który ma być bezgwintowy i nie wymaga ochrony współbieżności. Chcesz połączyć wezwania do odroczonego wykonania. Wzorzec, który podążam za tym, to użycie wywołań zwrotnych. Coś takiego:
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); } }); } }
Można to również zaimplementować za pomocą detektorów zdarzeń DOM lub rozwiązania pubsub.
źródło
JavaScript, z nielicznymi wyjątkami (
XMLHttpRequest
onreadystatechange
programy obsługi w niektórych wersjach Firefoksa) , jest współbieżna w pętli zdarzeń . Nie musisz więc martwić się o blokowanie w tym przypadku.Aby uzyskać więcej linków na temat współbieżności pętli zdarzeń, zobacz E
źródło
Miałem obietnicę sukcesu .
Zgadzam się z innymi odpowiedziami, że możesz nie potrzebować blokowania w swoim przypadku. Ale nie jest prawdą, że nigdy nie trzeba blokować w JavaScript. Potrzebujesz wzajemnej wyłączności podczas uzyskiwania dostępu do zasobów zewnętrznych, które nie obsługują współbieżności.
źródło
Zamki to koncepcja wymagana w systemie wielowątkowym. Nawet w przypadku wątków roboczych komunikaty są wysyłane według wartości między procesami roboczymi, dzięki czemu blokowanie nie jest konieczne.
Podejrzewam, że musisz po prostu ustawić semafor (system flagowania) między przyciskami.
źródło
Dlaczego nie wyłączysz przycisku i nie włączysz go po zakończeniu wydarzenia?
<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>
Miłego kodowania !!!
źródło
Jakiś dodatek do odpowiedzi JoshRivera w moim przypadku;
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); });
Będzie tylko jedno wywołanie interfejsu API i te dwie funkcje będą zużywać ten sam wynik.
źródło
Zamki nadal mają zastosowanie w JS. Z mojego doświadczenia wynika, że potrzebowałem tylko blokad, aby zapobiec klikaniu spamu na elementach wykonujących połączenia AJAX. Jeśli masz program ładujący skonfigurowany do połączeń AJAX, nie jest to wymagane (a także wyłączanie przycisku po kliknięciu). Ale tak czy inaczej, oto czego użyłem do zablokowania:
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]; }
Stosowanie:
Ręczne odblokowanie (zwykle dla XHR)
LockCallback('someKey',(delCallback) => { //do stuff delCallback(); //Unlock method }, true)
Automatyczne odblokowanie
LockCallback('someKey',() => { //do stuff })
źródło
Oto prosty mechanizm blokujący, realizowany poprzez zamknięcie
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
źródło