这可以在没有同步AJAX的情况下完成吗?
问题描述:
出于性能原因,我想将我的以下代码从同步更改为异步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);
}
});
答
你的直觉是正确的:不要做同步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机制时那样设置。
答
试试这个(未经测试):
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);
});