2011-08-05 53 views
1

我試圖做一個內發送多個崗位一段時間,但不會添加循環的結果待辦事項而JavaScript的問題

<script type="text/javascript"> 
function action() { 
    var initval = 1; 
    var endval = 5; 
    do { 
    var action_string = 'txtuser=someone'; 

    $.ajax({ 
        type: "POST", 
        url: "http://localhost/js.php", 
        data: action_string, 
        success: function(result){ 
         $('div#append_result').append(initval + ',<br/>'); 
        } 
       }); 
    initval++; 
    } while (initval <= endval); 
    } 
</script> 

輸出是: 5, 5, 5, 5, 5,

和我需要的輸出爲: 1, 2, 3, 4, 5,

回答

6

由於AJAX的異步性質,當您的成功函數針對任何生成的AJAX請求運行時,循環已完成且initval設置爲5.您需要在每個請求的開始時捕獲initval的狀態並在success()方法中使用該捕獲狀態。關閉了價值在於做最簡單的方法:

function action() { 
    var initval = 1; 
    var endval = 5; 
    do { 
     var action_string = 'txtuser=someone'; 

     (function(captured_initval){ 
      $.ajax({ 
       type: "POST", 
       url: "http://localhost/js.php", 
       data: action_string, 
       success: function(result){ 
        $('div#append_result').append(captured_initval + ',<br/>'); 
       } 
      }); 
     }(initval)); 

     initval++; 
    } while (initval <= endval); 
} 

瞭解,雖然,一個或多個請求可以在服務器允許後者則要求首先要完成,這可能導致1, 2, 5, 3, 4或東西先掛了像那樣。

此外,使用元素的ID比使用元素標記名稱爲散列選擇器添加前綴要快得多。另外,每當成功運行時,您應避免重新查詢DOM的結果DIV。抓取一次,並在需要時使用它:

function action() { 
    var initval = 1; 
    var endval = 5; 
    do { 
     var action_string = 'txtuser=someone', 
      $AppendResult = $('#append_result'); 

     (function(captured_initval){ 
      $.ajax({ 
       type: "POST", 
       url: "http://localhost/js.php", 
       data: action_string, 
       success: function(result){ 
        $AppendResult.append(captured_initval + ',<br/>'); 
       } 
      }); 
     }(initval)); 

     initval++; 
    } while (initval <= endval); 
} 
+1

您不是「關閉」* interval *的值,您正在避免關閉(仍然存在)的影響。 – RobG

+0

非常正確,我正在避免原封閉的影響。但是,我是不是通過創建一個新的作用域來創建一個我喜歡的效果的閉包?請記住,成功回調駐留在我創建的立即調用的函數表達式中,導致「捕獲」值被關閉... – JAAulde

+1

非常非常感謝,都是有幫助的! – blackriderws

3

Ajax請求是異步的,這意味着當成功處理程序返回時,循環已完成。相反,你可以創建一個封閉保存價值:

success: (function(i){ 
    return function() { 
     $('div#append_result').append(i + ',<br/>'); 
    } 
})(initval) 
+1

這不是一個閉包,它避免了閉包的影響。匿名函數仍然有一個關閉initval。 – RobG

+0

@RobG - 正如我在回答我對自己答案的評論時所說的,我恭敬地不同意。 – JAAulde

+0

@JAAulde - 其實我們同意。但是,額外的關閉是一個副作用,而不是原始關閉被打破的原因。換句話說,它現在起作用的事實並不是因爲額外的關閉,而是因爲將值傳遞給另一個函數(並且只是因爲該值是一個原語)。 – RobG

2

這是因爲AJAX的異步行爲: 下面是修改後的版本:

var initval = 1; 
var endval = 5; 
function action(){ 
    var action_string = 'txtuser=someone'; 
    $.ajax({ 
     type: "POST", 
     url: "http://localhost/js.php", 
     data: action_string, 
     success: function(result){ 
      $('div#append_result').append(initval + ',<br/>'); 
      initval++; 
      if(initval<=endval) 
      action(); 
     } 
    }); 
} 

這是現在有些順序方法。 注意:我認爲每個Ajax請求都會返回成功,如果出現錯誤,您應該在錯誤回調中處理它們。