开发者

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);
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜