Zabránění konfliktu Javascriptu

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