2011-03-22 115 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); 
}); 
相关问题