Can this be done without synchronous AJAX?
I'd like to change my following code from synchronous to async AJAX for performance reasons. Is this possible? I'm finding that almost all of my AJAX calls are synchronous, so I sense that I'm missing a design pattern. In general, if you need to display data that is returned from the server, then don't you need to wait (async: false) for the server to respond with data before you can continue?
In the code below, the element 'a.popup' has two 'click' handlers bound to it. The first is a lightbox (not shown) and the second is the code shown below. I tried doing this without "async: false", but it doesn't work.
function completed_investment($inputs) {
var result;
jQuery.ajax开发者_Go百科({
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);
}
});
Your instincts are correct: don't do synchronous AJAX. Instead, put the code that expects the "result" inside the "success" callback!
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);
}
});
Then change the function that makes the AJAX call:
function completed_investment($inputs, whenFinished) {
var result;
jQuery.ajax({
type: 'POST',
url: '/ajax/completed_investment',
dataType: 'json',
data: $inputs,
async: true,
success: function(data) {
whenFinished(data);
}
});
}
The basic idea in JavaScript is that since it's so easy to just wrap some code up in an anonymous function and toss it around, there's no need to have code "wait" as you describe. Instead, you simply package up the work and hand it over to the service function for use as an event handler. When the HTTP request finishes, that occurrence will trigger the event, and your handler is called. Because of the scoping rules in JavaScript, the local variables available to your code are still available exactly as they were set when the handler function was passed in to the AJAX mechanism.
Try this (untested):
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);
});
精彩评论