Aquí está el escenario:Evitar una condición de carrera de javascript
A mis usuarios se les presenta una grilla, básicamente, una versión simplificada de una hoja de cálculo. Hay cuadros de texto en cada fila de la grilla. Cuando cambian un valor en un cuadro de texto, estoy validando su entrada, actualizando la colección que está manejando la cuadrícula y redibujando los subtotales en la página. Todo esto se maneja mediante el evento OnChange de cada cuadro de texto.
Cuando hacen clic en el botón "Guardar", estoy utilizando el evento OnClick del botón para realizar una validación final de los importes y luego enviar su entrada completa a un servicio web, guardándola.
Al menos, eso es lo que ocurre si tabulan en el formulario el botón Enviar.
El problema es que, si introducen un valor, inmediatamente hacen clic en el botón Guardar, SaveForm() comienza a ejecutarse antes de que UserInputChanged() complete - una condición de carrera. Mi código no utiliza setTimeout, pero yo estoy usando para simular el código de validación UserInputChanged lenta:
<!-- snip -->
<script>
var amount = null;
var currentControl = null;
function UserInputChanged(control) {
currentControl = control;
// use setTimeout to simulate slow validation code (production code does not use setTimeout)
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; // update subtotals
}
</script>
<!-- snip -->
Amount: <input type="text" id="UserInputValue" onchange="UserInputChanged(this);" /> <br />
Subtotal: <span id="Subtotal"></span> <br />
<input type="button" onclick="SaveForm();" value="Save" /> <br /><br />
Saved amount: <span id="SavedAmount"></span>
<!-- snip -->
No creo que pueda acelerar el código de validación - que es bastante ligero, pero al parecer, lento suficiente como para que el código intente llamar al servicio web antes de que se complete la validación.
En mi máquina, ~ 95ms es el número mágico entre si el código de validación se ejecuta antes de que comience el código de guardado. Esto puede ser mayor o menor dependiendo de la velocidad de la computadora del usuario.
¿Alguien tiene alguna idea de cómo manejar esta condición? Un compañero de trabajo sugirió usar un semáforo mientras el código de validación se está ejecutando y un bucle ocupado en el código de guardado para esperar hasta que el semáforo se desbloquee, pero me gustaría evitar el uso de cualquier tipo de bucle ocupado en mi código.
Exactamente lo que necesito. ¡Gracias! –