Call functions for ajax request inside callback

1

Within a function callback() of a click need to make at least 3 requests.

I separated this into three functions: (func1(), func2() e func3()) and each of them makes a request ajax ($.get) returning me true or false . If the func1() returns true the func2() can be called and, if the func2() returns true the func3() can be called. If any of the func() returns me false I can not proceed with the func following.

How can I do this, because that way it is not returning true or false, it is returning undefined .

Link to jsfiddle: Code

$('#chamar').bind('click',
            function () {
                $('#form').validator().on('submit', function (e) {
                    if (e.isDefaultPrevented()) {
                        // handle the invalid form...
                    } else {

                    if(func1()==false){
                            //aqui ele ja deveria finalizar e não fazer a proxima requisição
                        alert("Função 1 falhou");
                    }

                     if(func2()==false){
                            //aqui ele ja deveria finalizar e não fazer a proxima requisição
                        alert("Função 2 falhou");
                    }

                    if(func3()==false){
                            //aqui ele ja deveria finalizar e não fazer a proxima requisição
                        alert("Função 3 falhou");
                    } 
                        alert("Todas as requisições foram feitas");
                    }
                })


            });

function func1() {

        $.get('consulta1.php?type=dado&action=get', {
                id: $('#id').val(),

            },function (e) {
                e = $.parseJSON(e);
                if (e[0].status) {
                    alert("DEU VERDADEIRO");
                    return true;
                } else {
                    alert("DEU FALSO");
                    return false;
                }
            }).fail(function () {
            alert("DEU FALSO");
            return false;
        });
    }

function func2() {

        $.get('consulta2.php?type=dado&action=get', {
                id: $('#id').val(),

            },function (e) {
                e = $.parseJSON(e);
                if (e[0].status) {
                    alert("DEU VERDADEIRO");
                    return true;
                } else {
                    alert("DEU FALSO");
                    return false;
                }
            }).fail(function () {
            alert("DEU FALSO");
            return false;
        });
    }

function func3() {

        $.get('consulta3.php?type=dado&action=get', {
                id: $('#id').val(),

            },function (e) {
                e = $.parseJSON(e);
                if (e[0].status) {
                    alert("DEU VERDADEIRO");
                    return true;
                } else {
                    alert("DEU FALSO");
                    return false;
                }
            }).fail(function () {
            alert("DEU FALSO");
            return false;
        });
    }
    
asked by anonymous 12.11.2017 / 15:11

3 answers

2

It always returns undefined because the ajax requests are asynchronous, so they only run much later, however the function is already finished because it did not wait for the request to be finished. This is the principle of asynchronism.

Consider the following structure identical to the one you are using:

function func1() {
  $.get(url, { dados }, function (e) { 
      ... 
      return ...;
  }).fail(function () {
    ...
    return ...;
  });

  //<----- Este é o valor que está a ser retornado, que é undefined pois a função não fica 
  //bloqueada à espera que o pedido get termine, simplesmente faz o pedido e continua. 
  //Se ficasse bloqueada à espera então era um pedido síncrono.
}

The solution to get the values for each order and make decisions based on this is to pass callbacks to what you want to do when the order is finished.

Applying this pattern to this func1 would look like this:

function func1(callback /*callback passado aqui*/) {
  $.get(url, { dados }, function (e) { 
      ...
      callback(true); //chamar o callback com true que indica sucesso
  }).fail(function () {
      ...
      callback(false); //chamar o callback com false que indica não sucesso
  });
}

And now when calling func1 it passes a function like callback which receives as a first parameter a boolean indicating whether it succeeded or not:

func1(function (resultado) {
    alert(resultado); //vem true ou falso com base no resultado do pedido ajax
});

Applying this idea to your code:

function func1(callback) {
    $.get('consulta1.php?type=dado&action=get', 
        { id: $('#id').val() },
        function (e) {
            e = $.parseJSON(e);
            callback(e[0].status?true:false);
        }).fail(function () {
            callback(false);
        });
}

function func2(callback) {
    $.get('consulta2.php?type=dado&action=get', 
        { id: $('#id').val() },
        function (e) {
            e = $.parseJSON(e);
            callback(e[0].status?true:false);
        }).fail(function () {
            callback(false);
        });
}

function func3(callback) {
    $.get('consulta3.php?type=dado&action=get', 
        { id: $('#id').val() },
        function (e) {
            e = $.parseJSON(e);
            callback(e[0].status?true:false);
        }).fail(function () {
            callback(false);
        });
}

And click becomes:

$('#form').validator().on('submit', function (e) {
    if (e.isDefaultPrevented()) {
        // handle the invalid form...
    } else {
        func1( function(resultado1){
            if (!resultado1){
                alert("Função 1 falhou");
            }
            else {
                func2( function(resultado2){
                    if (!resultado2){
                        alert("Função 2 falhou");
                    }
                    else {
                        func3( function(resultado3){
                            if (!resultado3){
                                alert("Função 3 falhou");
                            }
                            else {
                                alert("Todas as requisições foram feitas");
                            }
                        });
                    }
                });
            }
        });
    }
});

$('#chamar').bind('click', function () {
    $("#form").submit();
});

Notice that every subsequent call increases the level of chaining of functions within functions. This was the purpose of creating Promises , where chaining is done by calling then at the end of each Promise which does not nest threads and becomes simpler to use.

Also the form validation function should not be set within the button's click otherwise it will accumulate multiple handlers of clicks which make the code run more and more times as you click.

Looking at your functions func1 , func2 and func3 I see that they are equal to the url exception. So simplify and generalize a function for all three:

function funcN(url, seletor, callback) {
    $.get(url, 
        { id: $(seletor).val() },
        function (e) {
            e = $.parseJSON(e);
            callback(e[0].status?true:false);
        }).fail(function () {
            callback(false);
        });
}

You can now use this function for all three requests by changing only url . I set the seletor as parameter also if you want to be able to call another element other than #id .

The usage would be:

$('#form').validator().on('submit', function (e) {
    if (e.isDefaultPrevented()) {
        // handle the invalid form...
    } else {
        funcN( function('consulta1.php?type=dado&action=get','#id',resultado1){
            if (!resultado1){
                alert("Função 1 falhou");
            }
            else {
                funcN( function('consulta2.php?type=dado&action=get','#id',resultado2){
                    if (!resultado2){
                        alert("Função 2 falhou");
                    }
                    else {
                        funcN( function('consulta3.php?type=dado&action=get','#id',resultado3){
                            if (!resultado3){
                                alert("Função 3 falhou");
                            }
                            else {
                                alert("Todas as requisições foram feitas");
                            }
                        });
                    }
                });
            }
        });
    }
});

$('#chamar').bind('click', function () {
    $("#form").submit();
});
    
12.11.2017 / 17:39
0

You can call func2 in func1 , and func3 in func2 , similar to callback .

It will look like this:

$('#chamar').bind('click',
  function () {
    $('#form').validator().on('submit', function (e) {
      if (e.isDefaultPrevented()) {
        // handle the invalid form...
      } else {
         func1();
      }
  }        
});

Implementation of func1() :

function func1() {
  $.get('consulta1.php?type=dado&action=get', {
    id: $('#id').val(),
  }, function (e) {
    e = $.parseJSON(e);
    if (e[0].status) {
      alert("DEU VERDADEIRO");
      // Chama a func2()
      func2();
      return;
    } else {
      alert("DEU FALSO");
      return;
    }
  }).fail(function () {
    alert("DEU FALSO");
    return;
  });
}

Impaction of func2() :

function func2() {
  $.get('consulta2.php?type=dado&action=get', {
    id: $('#id').val(),
  },function (e) {
    e = $.parseJSON(e);
    if (e[0].status) {
      alert("DEU VERDADEIRO");
      // Chama a func3();
      func3();
      return;
    } else {
      alert("DEU FALSO");
      return;
    }
  }).fail(function () {
    alert("DEU FALSO");
    return;
  });
}
    
12.11.2017 / 16:54
0

I believe using a Promise is more appropriate for you.

var ajax = function (method, url, data) {
  return new Promise(function (resolve, reject) {
    var request = new XMLHttpRequest();
    request.open(method, url);
    request.addEventListener("readystatechange", function (evt) {
      if (request.readyState == 4) {
        if (request.status == 200) {
          if (request.response[0].status) {
            resolve("Retorno: Verdadeiro");
          } else {
            reject("Retorno: Falso");
          }
        } else {
          reject("Retorno: Error => " + request.statusText);
        }
      }
    });
    request.responseType = "json";
    request.send(data);
  });
}

var data = { id: document.getElementById("id").value };
ajax("GET", "consulta1.php?type=dado&action=get", data)
.then(function (msg) {
  console.log(msg);
  return ajax("GET", "consulta2.php?type=dado&action=get", data);
})
.then(function (msg) {
  console.log(msg);
  return ajax("GET", "consulta3.php?type=dado&action=get", data);
})
.then(function (msg) {
  console.log(msg);
})
.catch(function (msg) {
  console.log(msg);
})
<input id="id" type="hidden" value="123" />
    
13.11.2017 / 16:37