Mým uživatelům je prezentována v podstatě zkrácená verze tabulky. V každém řádku mřížky jsou textová pole. Když změní hodnotu v textovém poli, provádím ověření jejich vstupu, aktualizuji kolekci, která řídí mřížku, a překresluji mezisoučty na stránce. To vše řeší OnChange
událost každého textového pole.
Když kliknou na Uložit tlačítko, používám OnClick
tlačítka událost pro provedení konečného ověření částek a poté odeslání celého jejich vstupu webové službě a jeho uložení.
Alespoň to se stane, pokud projdou formulářem na Odeslat tlačítko.
Problém je v tom, že pokud zadají hodnotu, okamžitě kliknou na tlačítko uložit SaveForm()
spustí se před UserInputChanged()
dokončí — podmínka závodu. Můj kód nepoužívá setTimeout
, ale používám ho k simulaci pomalého UserInputChanged
ověřovací kód:
<script> var amount = null; var currentControl = null; function UserInputChanged(control) { currentControl = control; // use setTimeout to simulate slow validation code setTimeout(ValidateAmount, 100); } function SaveForm() { // call web service to save value document.getElementById("SavedAmount").innerHTML = amount; } function ValidateAmount() { // various validationey functions here amount = currentControl.value; // save value to collection document.getElementById("Subtotal").innerHTML = amount; } </script> Amount: <input type="text" onchange="UserInputChanged(this)"> Subtotal: <span id="Subtotal"></span> <button onclick="SaveForm()">Save</button> Saved amount: <span id="SavedAmount"></span>
Nemyslím si, že mohu urychlit ověřovací kód – je docela lehký, ale zjevně dostatečně pomalý na to, aby se kód pokusil zavolat webovou službu před dokončením ověření.
Na mém počítači je ~95 ms magické číslo mezi tím, zda se ověřovací kód spustí, než začne kód uložení. Ta může být vyšší nebo nižší v závislosti na rychlosti počítače uživatele.
Má někdo nějaký nápad, jak tento stav řešit? Kolega navrhl používat semafor, zatímco je spuštěn ověřovací kód a zaneprázdněná smyčka v kódu pro uložení, aby se počkalo, až se semafor odemkne – ale rád bych se vyhnul použití jakékoli zaneprázdněné smyčky v mém kódu.
Odpověď
Použijte semafor (říkejme tomu StillNeedsValidating). pokud funkce SaveForm vidí, že semafor StillNeedsValidating je aktivní, nechte ji aktivovat druhý vlastní semafor (který zde nazvu FormNeedsSaving) a vraťte se. Po dokončení ověřovací funkce, pokud je zapnutý semafor FormNeedsSaving, sám o sobě zavolá funkci SaveForm.
V jankcode;
function UserInputChanged(control) { StillNeedsValidating = true; // do validation StillNeedsValidating = false; if (FormNeedsSaving) saveForm(); } function SaveForm() { if (StillNeedsValidating) { FormNeedsSaving=true; return; } // call web service to save value FormNeedsSaving = false; }