我的用户看到的基本上是一个精简版的电子表格。网格中的每一行都有文本框。当他们更改文本框中的值时,我正在对他们的输入执行验证,更新驱动网格的集合,并重新绘制页面上的小计。这一切都由OnChange
每个文本框的事件处理。
当他们单击Save按钮时,我正在使用按钮的OnClick
事件对金额执行一些最终验证,然后将他们的整个输入发送到 Web 服务,并保存它。
至少,如果他们通过表单切换到Submit按钮,就会发生这种情况。
问题是,如果他们输入一个值,然后立即单击保存按钮,在完成SaveForm()
之前开始执行UserInputChanged()
——竞争条件。我的代码不使用setTimeout
,但我用它来模拟缓慢的UserInputChanged
验证代码:
<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>
我认为我无法加快验证代码的速度——它非常轻量级,但显然速度很慢,以至于代码会在验证完成之前尝试调用 Web 服务。
在我的机器上,~95ms 是在保存代码开始之前验证代码是否执行之间的幻数。这可能更高或更低,具体取决于用户的计算机速度。
有谁知道如何处理这种情况?一位同事建议在验证代码运行时使用信号量,并在保存代码中使用繁忙循环等待信号量解锁 - 但我想避免在我的代码中使用任何类型的繁忙循环。