2011-03-22 151 views
1

出於性能原因,我想將我的以下代碼從同步更改爲異步AJAX。 這可能嗎? 我發現幾乎所有的AJAX調用都是同步的,所以我覺得我錯過了一個設計模式。一般來說,如果您需要顯示從服務器返回的數據,那麼在您可以繼續之前,您是否需要等待(async:false)讓服務器響應數據?這可以在沒有同步AJAX的情況下完成嗎?

在下面的代碼中,元素'a.popup'有兩個綁定到它的'click'處理程序。第一個是燈箱(未顯示),第二個是下面顯示的代碼。我試圖做到這一點沒有「async:false」,但它不起作用。

function completed_investment($inputs) { 

     var result; 

     jQuery.ajax({ 
      type: 'POST', 
      url: '/ajax/completed_investment', 
      dataType: 'json', 
      data: $inputs, 
      async: false,   // need to wait until get result. 
      success: function(data) { 
       result = data; 
      } 
     }); 
     return result; 
} 


// AJAX - Completed 
jQuery('a.open-popup').click(function(){ 
    var $parent = jQuery(this).parent(); 
    var $InvestmentID = $parent.siblings('input').attr('value'); 
    var $inputs; 
    var $outputs; 

    $inputs = { 'InvestmentID' : $InvestmentID }; 
    $outputs = completed_investment($inputs); 

    // If an investment was completed, update HTML 
    if ($outputs.state == 'Begin') 
    { 

     $parent.siblings('.plan-msg').remove(); 
     $parent.removeClass('completed-button') 
        .addClass('add-inv-button ') 
        .html('+ Add to Your Plan'); 
     $newpoints = '(+' + $outputs.points + " " + $outputs.plural + ")"; 
     $parent.siblings('.done-points').removeClass('done-points') 
             .addClass('add-points') 
             .html($newpoints); 
    } 
}); 

回答

1

你的直覺是正確的:不要做同步AJAX。取而代之的是,把期望「結果」的代碼放在的「成功」回調中!

jQuery('a.open-popup').click(function(){ 
    var $parent = jQuery(this).parent(); 
    var $InvestmentID = $parent.siblings('input').attr('value'); 
    var $inputs; 
    var $outputs; 

    $inputs = { 'InvestmentID' : $InvestmentID }; 
    $outputs = completed_investment($inputs, function($outputs) { 
     if ($outputs.state == 'Begin') 
     { 

      $parent.siblings('.plan-msg').remove(); 
      $parent.removeClass('completed-button') 
       .addClass('add-inv-button ') 
       .html('+ Add to Your Plan'); 
      $newpoints = '(+' + $outputs.points + " " + $outputs.plural + ")"; 
      $parent.siblings('.done-points').removeClass('done-points') 
            .addClass('add-points') 
            .html($newpoints); 
     } 
    }); 

然後改變,使AJAX調用的函數:

function completed_investment($inputs, whenFinished) { 

    var result; 

    jQuery.ajax({ 
     type: 'POST', 
     url: '/ajax/completed_investment', 
     dataType: 'json', 
     data: $inputs, 
     async: false,   // need to wait until get result. 
     success: function(data) { 
      whenFinished(data); 
     } 
    }); 
} 

JavaScript中的基本思路是,因爲它是那麼容易只是包裝一些代碼了在一個匿名函數折騰它,沒有必要讓代碼「等待」,正如你所描述的那樣。相反,您只需打包工作並將其交給服務功能以用作事件處理程序。當HTTP請求完成時,該事件將觸發事件,並調用您的處理程序。由於JavaScript中的範圍規則,您的代碼可用的局部變量仍然可以像處理函數傳遞給AJAX機制時那樣設置。

0

試試這個(未經測試):

function completed_investment($inputs) { 
    jQuery.ajax({ 
     type: 'POST', 
     url: '/ajax/completed_investment', 
     dataType: 'json', 
     data: $inputs, 
     async: false,   // need to wait until get result. 
     success: function($outputs) { 
      // If an investment was completed, update HTML 
      if ($outputs.state == 'Begin') 
      { 

       $parent.siblings('.plan-msg').remove(); 
       $parent.removeClass('completed-button') 
          .addClass('add-inv-button ') 
          .html('+ Add to Your Plan'); 
       $newpoints = '(+' + $outputs.points + " " + $outputs.plural + ")"; 
       $parent.siblings('.done-points').removeClass('done-points') 
        .addClass('add-points') 
        .html($newpoints); 
      } 
     } 
    }); 
    // Notice: no return value 
} 


// AJAX - Completed 
jQuery('a.open-popup').click(function(){ 
    var $parent = jQuery(this).parent(); 
    var $InvestmentID = $parent.siblings('input').attr('value'); 
    var $inputs; 

    $inputs = { 'InvestmentID' : $InvestmentID }; 
    completed_investment($inputs); 
}); 
相關問題