2012-08-07 122 views
0

在我的Web應用程序中,我爲文本框定義了一個更改事件,該事件正在調用ajax方法並將文本框值存儲到會話中。我有一個名爲「test」的按鈕,它將檢查文本框中輸入文本的驗證,它將從會話中獲取字符串並進行驗證。javascripts中的競態條件

<html> 
<head> 
<script type="text/javascript"> 
$(document).ready(function(){  
    $("input", form).change(function() { 
      //using ajax to store the text value to session 
     }); 

    $("#validateAmt").click(function() { 
      //using another ajax to check the value stored in session 
     }); 
}); 
</script> 
</head> 
<body> 
    <input type="text" id="amount"> 
    <input type="button" id="validateAmt" value="validate"/> 
</body> 
</html> 

但有時會發生什麼情況是,當我在文本框,無需點擊以外的任何地方進入的東西,如果我在「測試」按鈕,直接點擊,其中按鈕事件首先觸發(這與會話舊值驗證)和文本框更改事件觸發器。所以目前我想在JavaScript中使用布爾標誌並調用第一個文本框更改事件。對於這種情況有沒有任何有效的解決方案?而且這些方法將如何執行?它會一個接一個地並行發生還是繼發發生?

+2

什麼是這一切的地步,只是驗證時被提交 – Esailija 2012-08-07 18:04:18

+0

形式禁用按鈕,直到文本框調用返回。 – asawyer 2012-08-07 18:09:15

+0

JavaScript沒有線程,所以它會按順序運行。 – 2012-08-07 18:13:12

回答

0

不要依賴變化事件始終在其他事情發生之前開火。在發送到服務器之前,始終驗證您的數據(並始終在服務器上驗證)。

如果驗證是昂貴的(例如它需要ajax調用),那麼您可以添加一個優化來跟蹤特定值是否已被驗證,但這只是性能優化,而不是核心的一部分邏輯。

1

默認情況下,Ajax請求是異步執行的,所以你不能保證什麼時候請求會發生什麼。 由於changeclick之前應該觸發和所有的JavaScript是在一個單一的執行,你可以:

  • 讓你$.ajax通話的選項{ async : false },但是,這將使你的來電攔截

  • 你保持跟蹤哪些Ajax查詢正在運行,並且您在完成之前的ajax查詢時執行遺留的ajax查詢

這裏是一個可能的解決方案保持異步行爲:

​Service=new function(){ 
    var onGoingAjax = null; 
    var onComplete = null; 

    this.change = function() { 
    // Cancel previous call 
    if (onGoingAjax) onGoingAjax.abort(); 
    // Run the new Ajax call 
    onGoingAjax = $ajax({ /* options */ }); 
    onGoingAjax.done(function() { 
     // mark the ajax call as finished 
     onGoingAjax=null; 
     // process the second call (if any) 
     processComplete(); 
    }); 
    }; 

    this.click = function(){ 
    endFunc = function() { $ajax({ /* options */ }); }; 
    processComplete(); 
    }; 

    function processComplete() 
    { 
    // check if ajax still executing => the skip this call 
    if (onGoingAjax != null) return; 
    // check if a complete function is set => call it 
    if (onComplete) onComplete(); 
    // reset the complete function 
    onComplete = null; 
    }; 
}()​; 

$(document).ready(function(){ 
    $("input", form).change(Service.change); 
    $("#validateAmt").click(Service.click); 
});