Problem using counter variable within Xmlhttp/AJAX request

Asked

Viewed 58 times

1

When I run the following function I always get 0 as a result.
I’d like to know why and if I’m doing something wrong. The function cadastro_socios_xlsx receives an object and registers each instance of it in the database, accurate of the variable test (which should be incremented in a unit to each instance duly registered in the database) for a future check, but the 'test' variable only has its correct value when I put the console.log inside the request.onreadystatechange. I have tried using AJAX, but the same happens...

$(document).ready(function(){
    function cadastro_socios_xlsx(tabela){
        var teste = 0;
        for(linha of tabela){
            if(formata_cpf_cnpj(linha['CPF/CNPJ']) && valida_cpf_cnpj(linha['CPF/CNPJ'])){
                if(linha['CPF/CNPJ'] == 14){
                    var pessoa = "fisica";
                }else var pessoa = "juridica";
                if (typeof linha['EMAIL'] == 'undefined') {
                    var email = "";
                }else var email = linha['EMAIL'];
                if (typeof linha['COMPLEMENTO'] == 'undefined') {
                    var complemento = "";
                }else var complemento = linha['COMPLEMENTO'];
                var data_nasc = "";
                var telefone = linha['TELEFONE'].replace(" ", "");


                var dados = {
                    "socio_nome": linha['NOME/RAZÃO SOCIAL'],
                    "pessoa": pessoa,
                    "email": email,
                    "telefone": telefone,
                    "cpf_cnpj": linha['CPF/CNPJ'],
                    "rua": linha['ENDEREÇO'],
                    "numero": linha['NÚMERO'],
                    "complemento": complemento,
                    "bairro": linha['BAIRRO'],
                    "estado": linha['UF'],
                    "cidade": linha['CIDADE'],
                    "data_nasc": data_nasc,
                    "cep":linha['CEP']
                };
                var dados = JSON.stringify(dados);
                var request = new XMLHttpRequest();

                request.open('post', './cadastro_socio.php');
                request.send(dados);
                request.onreadystatechange = function() {
                    if(this.readyState == 4 && this.status == 200){
                        var r = JSON.parse(this.response);
                        if(r){
                            teste++;
                            //console.log(teste); quando coloco o console.log aqui ele mostra os valores incrementando
                        }
                    }
                }
                 //console.log(teste); quando coloco o console.log aqui ele sempre mostra o valor inicial da variável teste (0)
            }

        }
        return teste; //sempre retorna 0
    }

  • Matheus, this is happening, because a javascript request is asynchronous, so its function is returning even before the request has been completed, read: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/funcoes_asynchronas and https://Developer.mozilla.org/en/Docs/Web/Javascript/Reference/Operators/await

  • Thank you, I used AJAX synchronously and it worked. But I get a message on the console saying: [Deprecation] Synchronous Xmlhttprequest on the main thread is deprecated because of its detrimental effects to the end user’s Experience. For more help, check link, actually use synchronously ends up affecting a little performance by being able to make only one request at a time, but for now will serve.

2 answers

2


When booting XMLHttpRequest through the method open() with only two parameters you are informing the system that you are initiating an asynchronous request.

In an asynchronous request the function execution flow is not blocked when sends a request to the server with send(), callback code will only be executed when the server responds or timeout.

In a synchronous request, the execution flow of the function is interrupted and resumed only after the server provides a response, and the execution flow goes through the callback. The synchronous request does not accept timeout.

//Função de testes de requisição assíncrona HTTP simplificada
//O objetivo não é medir suceso ou não de uma requisição portanto:
//NÃO SERVE DE MODELO PARA CHAMADAS XMLHttpRequest
function testeAsync() {
  let teste = 0;
  let request = new XMLHttpRequest();
  request.timeout = 5000; //timeout 5s

  //Faz uma requisição assíncrona a uma API de testes 
  request.open('post', 'https://jsonplaceholder.typicode.com/posts');
  request.setRequestHeader('Content-type', 'application/json; charset=UTF-8');
  request.onreadystatechange = function(r) {
    if (this.readyState != 4 && this.status != 200) return;
    teste++;
    console.log(`Teste assíncrono dentro do callback : teste = ${teste}`);
  }
  //É uma requição assíncrona o que signific que o fluxo de execução NÃO será retido aqui 
  request.send({
    title: 'foo',
    body: 'bar',
    userId: 1
  });
  //Provavelmente esse código será executado primeiro que o equivalente dentro do callback, 
  //O que significa que teste++; ainda não foi executado provavelmente retornando teste = 0, mas não é uma certeza
  console.log(`Teste assíncrono fora do callback: teste = ${teste}`);
}

//Função de testes de requisição síncrona HTTP simplificada
//O objetivo não é medir suceso ou não de uma requisição portanto:
//NÃO SERVE DE MODELO PARA CHAMADAS XMLHttpRequest
function testeSync() {
  let teste = 0;
  let request = new XMLHttpRequest();

  //Faz uma requisição síncrona a uma API de testes 
  request.open('post', 'https://jsonplaceholder.typicode.com/posts', false);
  request.setRequestHeader('Content-type', 'application/json; charset=UTF-8');
  request.onreadystatechange = function(r) {
    if (this.readyState != 4 && this.status != 200) return;
    teste++;
    console.log(`Teste síncrono dentro do callback : teste = ${teste}`);
  }
  //É uma requição síncrona o que signific que o fluxo de execução SERÁ retido aqui. 
  request.send({
    title: 'foo',
    body: 'bar',
    userId: 1
  });
  //Esse código NÃO será executado primeiro que o equivalente dentro do callback, 
  //O que significa que teste++; com certeza foi executado retornando teste = 1
  console.log(`Teste síncrono fora do callback : teste = ${teste}`);
}


testeAsync();

testeSync();

0

From what vi can be a variable scope problem tries to return the variable "test" within the function "onreadystatechange", instead of outside it.

Browser other questions tagged

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