这里是场景:避免javascript竞争条件
我的用户呈现一个网格,基本上,一个电子表格的精简版。网格中的每一行都有文本框。当他们更改文本框中的值时,我将对其输入进行验证,更新驱动网格的集合,并在页面上重新绘制小计。这全部由每个文本框的OnChange事件处理。
当他们点击“保存”按钮时,我使用按钮的OnClick事件对金额进行一些最终验证,然后将其全部输入发送到Web服务并保存。
至少,如果他们通过表单选择“提交”按钮,会发生什么情况。
问题是,如果他们输入一个值,然后立即单击保存按钮,SaveForm()在UserInputChanged()完成之前开始执行 - 竞争条件。我的代码不使用setTimeout的,但我用它来模拟低迷UserInputChanged验证码:
<!-- 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 -->
我不认为我能加快验证码 - 它很轻便,但显然,缓慢足以让代码在验证完成之前尝试调用Web服务。
在我的机器上,~95ms是在保存代码开始之前验证代码是否执行的神奇数字。这取决于用户的计算机速度可能更高或更低。
有没有人有任何想法如何处理这种情况?一位同事建议在验证代码运行时使用信号量,并在保存代码中等待信号量解锁时出现忙碌循环 - 但我想避免在代码中使用任何类型的忙碌循环。
正是我需要的。谢谢! – 2008-12-03 18:13:48