Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

FUNCÃO CALLBACK

Uma dúvida sobre função callback.

Qual a diferença entre executar o código assim:

function addOne(callback) {
    --qualquer coisa....
    callback()
  }
}

function logMyNumber() {
  console.log(myNumber)
}

addOne(logMyNumber)

Ou assim:

function addOne() {
    --qualquer coisa....
     logMyNumber() 
  }
}

function logMyNumber() {
  console.log(myNumber)
}

Das duas formas a função logMyNumber não será executada no mesmo tempo de execução?

Estou com dúvida pra que serve esse callback em javascript.... sempre usei uma função dentro de outra função como na segunda forma, e não entendi a diferença entre usa-la como neste exemplo que coloquei onde dizem ser um callback...

Outra dúvida, no primeiro exemplo, não existe uma definição de parametro na função addOne dizendo que a escrita callback é uma função (function addOne(callback)) ... o js vai procurar por qualquer coisa chamada callback no código e se for uma função vai executar? Não precisa definir que é uma função?

Obrigado!

7 respostas

Olá, Marco Antonio.

Quando estamos desenvolvendo algo no backend é bem comum precisarmos de um banco de dados para guardar os informações que são enviadas do frontend para o backend. Em nosso código criamos objetivo que cuida apenas da comunicação com o banco de dados, chamamos esses objetos de DAO (Data Access Object).

O código a seguir faz uma consulta com o banco de dados e a nossa camada de view (visualização, onde normalmente temos uns HTML) que mostrar todos os produtos que temos cadastro no nosso banco de dados. Lembre-se que o DAO é responsável apenas por consultar os dados.

app.get('/produto',  function() {
    const produtoDao = new produtoDao()

    produtoDao.lista(function(produtosCadastradoNoBanco) {
        res.render('produtos.html', {produtos})
    })
})

Executamos o método lista() o produtoDao e esse método espera receber como argumento uma função e será nessa função que o produtoDao passará o resultado da consulta ao banco de dados por parâmetro que temos o nome de produtosCadastroNoBanco (não precisa dar esse tipo de nome para uma variável, só estou fazendo isso pra facilitar a explicação). Essa função que passamos para o método lista() é um exemplo de callback bem usado.

Agora vamos ver como fica o código do nosso ProdutoDao:

class ProdutoDao {
    lista(callback) {
       const connection = createConnection()

       connection.query('SELECT * FROM produtos', function(error, resultadoDaConsultaNoBanco) {
            callback(resultadoDaConsultaNoBanco)
        })
    }
}

Nessa caso o callback é uma boa solução porque podemos fazer um consulta no banco de dados e deixar a responsabilidade de como o dado será exibido para a cada de controller (camda responsável por falar com o DAO e passar a informação para a view e contrário também é verdade) e view.

Se não entender por favor avisa, é um assunto chato de entender no começo mas muito útil e também muito utilizado em linguagem que tratam eventos de forma assíncrona.

Primeiro obrigado pela resposta Marco Bruno!

Eu peguei o exemplo que estou "brincando" para entender... é mais simples...

Mas veja só a imagem:

https://uploaddeimagens.com.br/imagens/1-png-34e0e2e8-c8cb-4fe0-9c5c-0157f364d0ed

dizerAlgo é uma função com 2 parâmetros, pelo que você disse não importa o que sejam os parâmetros, pode ser um int, uma string etc etc correto?

Certo até ai ok...

Na linha 9, existe uma função "saida"...com um parâmetro "mensagem", essa função esta sendo chamada e não foi definida em nenhum lugar...apenas chamo ela como chamo qualquer função, ou seja, deveria dar um erro de is not defined certo? e o píor de tudo! dentro dela existe um parametro mensagem que ja esta com valor, o olá esta dentro dele! kkkkk

Em que momento esse valor foi definido, visto que eu debuguei e o codigo é executado na ordem decrescente de linhas....

segue o código fique mais facil de me explicar... Se salvar como html e abrir no navegador veras que incrivelmente funciona.... kkkkk

<html>
<head>

    <script>
        var pessoa = {
            nome: "João",
            idade: 35,
            dizerAlgo: function (mensagem, saida) {
            saida(mensagem);
        }   
        };

        pessoa.dizerAlgo("Olá", function(msg){
            window.alert(msg);
        });
    </script>    

</head>
<body>
</body>
</html>

Obrigado pela paciência!

dizerAlgo é uma função com 2 parâmetros, pelo que você disse não importa o que sejam os parâmetros, pode ser um int, uma string etc etc correto?

Isso mesmo.

O forma que você fez o callback não seria necessário um callback. Você poderia deixar o window.alert dentro do método dizAlgo:

var pessoa = {
  nome: "João",
  idade: 35,
  dizerAlgo: function (mensagem) {
    window.alert(msg);
  }   
};

pessoa.dizerAlgo("Olá");

Mas gostei bastante do seu exemplo, bem melhor do que o meu. Pegando a sua ideia você poderia implementar o callback com a seguinte necessidade. Imagine que você quer perguntar o nome para a pessoa se ela souber responder o nome dela você quer pegar o nome dela e falar pra ela Prazer Fulano (nesse caso João) e se você enviar uma resposta a essa pessoa que ela não sabe responder ela te já te responderia que ela não entendeu.

var pessoa = {
  nome: "João",
  idade: 35,
  responde: function (pergunta, saida) {
    if (pergunta == "Nome?") {
      saida(this.nome)
    } else {
      window.alert('Ixi! Não entendi o que você falou. Desculpa aí :-)')
    }
  }   
};

pessoa.responde("Nom?", function(msg){
  window.alert('Prazer ' + msg);
});

Nesse caso o callback é bem útil porque você precisa saber o nome da pessoa pra dar uma resposta da forma que você quiser. Utilizar Prazer João mas vamos dizer que você perguntou mais um vez o nome da pessoa e não quer ser mal educado e diz pra ela Desculpa ter perguntado novamente, João. Sou ruim pra guardar nomes:

var pessoa = {
  nome: "João",
  idade: 35,
  responde: function (pergunta, saida) {
    if (pergunta == "Nome?") {
      saida(this.nome)
    } else {
      window.alert('Ixi! Não entendi o que você falou. Desculpa aí :-)')
    }
  }   
};

pessoa.responde("Nom?", function(msg){
  window.alert('Prazer ' + msg);
});

pessoa.responde("Nom?", function(msg){
  window.alert('Desculpa ter perguntado novamente,' + msg + '. Sou ruim pra guardar nomes');
});

Por tanto uns dos melhores momentos pra se usar um callback é quando você precisa pegar um dado de um objeto e com o acesso a esse dado tratar ele da forma que quiser em momentos diferentes.

Ou seja resumindo...

O callback é como se fosse um subselect... você precisa de um dado ou que uma ação (função secundaria) seja feita antes de executar o restante de sua função principal.... chama uma função dentro de outra e da o nom disso de callback... certo?

solução!

Isso aí é um bom caminho de definição. Só não se esquema que é bem usado pra lidar com coisas assíncronas :-)

Obrigado pela ajuda e pela paciência!

Não é paciência não. É muito bom quando consegui ensinar algo pra alguém :-)