0

I have tasks that I want to do synchronously; but I don't want to freeze the browser. There could be 1---N tasks.

Below is the synchronous version. It works as expected but freezes the browser.

How can I do this using jQuery deferred object to do these task in order but not lock browser.

NOTE: The server I am request to does NOT allow for 2 requests at once. They need to run one after the other once the request is finished in exact order.

<?php
for ($k = 0;$k<count($partial_transactions);$k++)
{
?>
    $("#formCheckout_<?php echo $k; ?>").ajaxSubmit({
        success:function(response)
        {
            var data = response.split("&");
            var processed_data = [];

            for(var i = 0; i < data.length; i++)
            {
                var m = data[i].split("=");
                processed_data[m[0]] = m[1];
            }           

            $("#please_wait").hide();

            if (processed_data.CmdStatus != 'Approved')
            {
                var message = decodeURIComponent(message);
                message =  processed_data.TextResponse.replace(/\+/g, ' ');
                toastr['error'](<?php echo json_encode(lang('sales_attempted_to_reverse_partial_transactions_failed_please_contact_support'));?>, <?php echo json_encode(lang('common_error')); ?>);
            }
            else
            {
                toastr['success'](<?php echo json_encode(lang('sales_partial_credit_card_transactions_voided')); ?>, <?php echo json_encode(lang('common_success')); ?>);
            }
        },
        cache: true,
        headers: false,
        async: false
    });
<?php
}
?>
5
  • 2
    have the AJAX calls asynchronous, but call next AJAX service in success callback of previous AJAX service Commented Jun 23, 2015 at 21:23
  • How would I do this for n number of transactions? It is easy for 2; but n is tough. Commented Jun 23, 2015 at 21:24
  • you might need to use for loop but ajax call with closure with i Commented Jun 23, 2015 at 21:26
  • @ChrisMuench You wanted a solution using jquery's Deferred object. I answered but didn't received any feedback, so if you're not interested anymore in a solution to your question I'm going to delete my answer in a few days. Commented Jun 25, 2015 at 17:42
  • I liked the solution but when @vinayakj suggestion was easier. Commented Jun 25, 2015 at 17:56

3 Answers 3

1

Try this:

var counter = 0;
// Build up an array of all forms that are to be submitted sequentially.
var forms = [
<?php
   for ($k = 0;$k<count($partial_transactions);$k++){
    if($k == 0){
        echo "#formCheckout_{$k}";
    }else{
       echo ", #formCheckout_{$k}"; 
    }
}
?>
];
// Start the request
make_next_request(forms[counter]);

function make_next_request(form){ 
    form.ajaxSubmit({
        success:function(response)
        {
            var data = response.split("&");
            var processed_data = [];

            for(var i = 0; i < data.length; i++)
            {
                var m = data[i].split("=");
                processed_data[m[0]] = m[1];
            }           

            $("#please_wait").hide();

            if (processed_data.CmdStatus != 'Approved')
            {
                var message = decodeURIComponent(message);
                message =  processed_data.TextResponse.replace(/\+/g, ' ');
                toastr['error'](<?php echo json_encode(lang('sales_attempted_to_reverse_partial_transactions_failed_please_contact_support'));?>, <?php echo json_encode(lang('common_error')); ?>);
            }
            else
            {
                toastr['success'](<?php echo json_encode(lang('sales_partial_credit_card_transactions_voided')); ?>, <?php echo json_encode(lang('common_success')); ?>);
            }
            // Now chain request onto next form.
            if(counter < forms.length){
                counter++;
                make_next_request(forms[counter]);
            }
        },
        cache: true,
        headers: false,
        async: false
    });
}
Sign up to request clarification or add additional context in comments.

Comments

0

You could just put it all in a web worker that handles all the data, so the UI thread doesn't get interrupted (but you'll have to give the user some indication that the data is loading.)

See the web worker API for more info, but basically, web workers are native browser objects that allow you to have multi-threaded operations. In other words, your operations can run in the background while the user still interacts with the web page, and then when the operations are complete, they can notify the UI thread (the thread the user is currently on.)

This CPU-intensive data loading that you're talking about seems like a perfect use case for such an API.

Comments

0

I ended up doing it like this. The intensive part is server side. So I took some suggestions and came up with this. (Using recursion)

<script>
var num_transactions_to_void = <?php echo count($partial_transactions); ?>;
var max_index = num_transactions_to_void - 1;

if (num_transactions_to_void > 0)
{
    void_sale_request(0);
}

function void_sale_request(index)
{   
    if (index > max_index)
    {
        return;
    }

    $("#formCheckout_"+index).ajaxSubmit({
        success:function(response)
        {
            var data = response.split("&");
            var processed_data = [];

            for(var i = 0; i < data.length; i++)
            {
                var m = data[i].split("=");
                processed_data[m[0]] = m[1];
            }           

            $("#please_wait").hide();

            if (processed_data.CmdStatus != 'Approved')
            {
                var message = decodeURIComponent(message);
                message =  processed_data.TextResponse.replace(/\+/g, ' ');
                toastr['error'](<?php echo json_encode(lang('sales_attempted_to_reverse_partial_transactions_failed_please_contact_support'));?>, <?php echo json_encode(lang('common_error')); ?>);
            }
            else
            {
                toastr['success'](<?php echo json_encode(lang('sales_partial_credit_card_transactions_voided')); ?>, <?php echo json_encode(lang('common_success')); ?>);
            }

            void_sale_request(index + 1);
        },
        cache: true,
        headers: false
    });
}

</script>

1 Comment

yep.. as I said.. for loop.. closure with i(index) and next ajax call in previous call's success callback

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.