Track AJAX requests in progress

Asked

Viewed 249 times

1

I am working on a page where I have an update button, when clicking on it runs a series of AJAX requests to complete the data available on the screen (4 requests to be more exact).

Should the user click the update button, I would like to disable the button while all requests do not return, because if the user clicks on the button several times ends up generating several requests, which causes the browser also traverse (I did this test).

Is there any way to verify that the request has not yet been completed by jQuery himself? As far as I understand it, we only have the .done, .fail and .always to use, and only with these checks I cannot perform this validation to enable/disable the button.

I don’t know if it makes any difference, but I’m making the requisitions with the structure

$.post({},function(){});

Do you happen to know any solution that allows you to track whether the request is still in progress or not it would be possible?

  • 1

    Knows beforeSend: function(){}? You could put a control variable on it... Each request would define this variable, and at the end, they would all perform a function to check that the other requests have already been completed. If it’s any use to you, I can formulate an answer to that effect.

  • @Lipespry hmm, I took a look at it, could it be used in the $.post structure or just $.ajax? So, if I can perform a check if all of them haven’t come back to give "disabled" on my button, yes!

  • Man, I took a look superficial in the documentation of jQuery and, apparently, it does not have. But also has no difference of $.post() pro $.ajax()... You can even make a plugin to facilitate the reuse of the code... If you are interested, I can formulate an answer giving a solution to your problem.

  • @Lipespry if you can I accept yes.

1 answer

2


Is there any way to verify that the request has not yet been completed by jQuery himself?

A simple way would be to add a control variable. By completing the request of ajax, set a value on that variable. Do so on all 4 requests. Thus, use Promise .aways() of the requisition ajax.

i would like to disable the button while all requests do not return

Then we can do a function to check that all requests have been completed. If so, enable the button again...

I am performing the requisitions with the structure $.post({},function(){});

In that case, I’ll use $.ajax().

Recommended reading: Soen - $.post() vs $.ajax()

Theory explained, let’s go to code:

        var requisicoes = 0;

        $(function(){
            $('#btnIniciar').on('click', function(){
                $(this).prop('disabled', true); // Desabilitei o botão!

                fazerRequisicoes(); // Chamei as requisições

            });
        });

        function fazerRequisicoes()
        {

            // Requisição #1
            $.ajax({
                url: 'http://foo.bar.com.br/baz/1',
                method: 'post',
                dataType: 'html',
                // Tudo que vai passar via POST
                // Pode passar um form.serialize() também
                data: {
                    // Td que vai passar via post
                }
            })
            .done(function(ret){
                // Tudo que acontece quando terminar com sucesso
                console.log('Requisição #1 finalizada com sucesso.');
            })
            .fail(function(erro){
                // Tudo que acontece quando terminar com erro
                console.log('Requisição #1 finalizada com erro.');
            })
            .always(function(){
                // Tudo que acontece quando terminar
                // Seja com sucesso ou com erro
                // Como o nome sugere: sempre vai ser executado
                requisicoes++;
                console.log('Requisições terminadas: '+requisicoes);
                if (checaRequisicoes(4)) // Serão 4 requisições no total!
                    habilitaBtn();
            });

            // Requisição #2
            $.ajax({
                url: 'http://foo.bar.com.br/baz/2',
                method: 'post',
                dataType: 'html',
                // Tudo que vai passar via POST
                // Pode passar um form.serialize() também
                data: {
                    // Td que vai passar via post
                }
            }).done(function(ret){
                // Tudo que acontece quando terminar com sucesso
                console.log('Requisição #2 finalizada com sucesso.');
            }).fail(function(erro){
                // Tudo que acontece quando terminar com erro
                console.log('Requisição #2 finalizada com erro.');
            }).always(function(){
                // Tudo que acontece quando terminar
                // Seja com sucesso ou com erro
                // Como o nome sugere: sempre vai ser executado
                requisicoes++;
                console.log('Requisições terminadas: '+requisicoes);
                if (checaRequisicoes(4)) // Serão 4 requisições no total!
                    habilitaBtn();
            });

            // Requisição #3
            $.ajax({
                url: 'http://foo.bar.com.br/baz/3',
                method: 'post',
                dataType: 'html',
                // Tudo que vai passar via POST
                // Pode passar um form.serialize() também
                data: {
                    // Td que vai passar via post
                }
            }).done(function(ret){
                // Tudo que acontece quando terminar com sucesso
                console.log('Requisição #3 finalizada com sucesso.');
            }).fail(function(erro){
                // Tudo que acontece quando terminar com erro
                console.log('Requisição #3 finalizada com erro.');
            }).always(function(){
                // Tudo que acontece quando terminar
                // Seja com sucesso ou com erro
                // Como o nome sugere: sempre vai ser executado
                requisicoes++;
                console.log('Requisições terminadas: '+requisicoes);
                if (checaRequisicoes(4)) // Serão 4 requisições no total!
                    habilitaBtn();
            });

            // Requisição #4
            $.ajax({
                url: 'http://foo.bar.com.br/baz/4',
                method: 'post',
                dataType: 'html',
                // Tudo que vai passar via POST
                // Pode passar um form.serialize() também
                data: {
                    // Td que vai passar via post
                }
            }).done(function(ret){
                // Tudo que acontece quando terminar com sucesso
                console.log('Requisição #4 finalizada com sucesso.');
            }).fail(function(erro){
                // Tudo que acontece quando terminar com erro
                console.log('Requisição #4 finalizada com erro.');
            }).always(function(){
                // Tudo que acontece quando terminar
                // Seja com sucesso ou com erro
                // Como o nome sugere: sempre vai ser executado
                requisicoes++;
                console.log('Requisições terminadas: '+requisicoes);
                if (checaRequisicoes(4)) // Serão 4 requisições no total!
                    habilitaBtn();
            });
        }

        function checaRequisicoes(numRequisicoes)
        {
            if (requisicoes >= numRequisicoes)
                return true;
            else
                return false;
        }

        function habilitaBtn()
        {
            // Após tudo terminar, vai esperar 3 segundo pra habilitar o botão
            setTimeout(function(){
                $('#btnIniciar').prop('disabled', false);
            }, 3000);
            requisicoes = 0;
        }
<!DOCTYPE html>
<html>
<head>
    <title>Projeto secreto</title>
    <meta charset="utf-8">
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
    <body>

        <button type="button" id="btnIniciar">Iniciar requisições ajax</button>

    </body>
</html>

I made this code ignoring any good practice of aesthetics and dynamics, so that it is clear for better understanding.

As I said, you can create a Plugin for the requests of ajax, if there is similarity between your requests (not attached to the question). The purpose here is to show a simple form of "confer" if your requests have been completed (error or not) to re-enable the button.

  • 1

    @Viniciusgabriel In the end I didn’t even use beforeSend... That way you can do with your $.post()...

  • Dude, show! This structure is really good, thank you very much.

  • The . Always, is fired soon at function call?

  • 1

    No. The always is called right after the .done(). Or after the .fail(), if there is any error... Theoretically, it is called ALWAYS after the request.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.