這裏是場景:避免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