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

Angular evitar callback hell

Existe uma maneira de evitar o callback hell do Angular?

Eu observei no curso a questão das funções de callback, acredito que um projeto muito grande isso pode acabar afetando a legibilidade do código, mesmo adotando factory promisses para ajudar na modularização e organização do código.

No jQuery usava o $proxy() e no JS puro o bind() para cria uma função associada que tem o mesmo corpo da função original, fazendo com o bind() eu continuo tendo acesso aos elementos do Angular por exemplo?

5 respostas

AngularJS combate o callback hell desde a sua concepção. No treinamento eu mostro que o Angular pode fazer uso de promises e que elas ajudam a combater o callback hell. Inclusive mostro como criar um serviço "promissificado".

Callback hell é um problema de programação assíncrona, por isso não entendi quando você diz que usava $proxy e bind para resolver o problema. $proxy e o bind servem para você chamar outra função, seja de um objeto ou plain alterando o contexto dela, o this. Ainda assim, você precisa passar um parâmetro que indica qual função chamar. E mais, se um objeto não é necessário, você poderia ter usado um nome de função que ficaria ainda mais simples, sem precisar poluir seu parâmetro com $proxy.

Não entendi a relação... mas se quiser você pode criar funções e passá-las como parâmetro para a função then da promise.

solução!

Se você quer combater o callback hell, isto é, se quiser combater os problemas da legibilidade da programação assíncrona você precisa estudar promises e generators. Isso é acabar com o callback hell.

Mas nem todo navegador ainda suporta generators. Mas fique ligado nessa informação. Eu conseguiria fazer algo assim:

Q.wrap(function *() {
  var retorno  = yield $http.get('endereco');
  var retorno2 = yield $http.get('endereco2');
});

Veja que executo as duas linhas como se fossem síncronas, mas são assíncronas através de generator. Quando a primeira promise terminar, irá fazer o resume do generator que executará a linha seguinte. Tudo isso sem bloquear o event loop do Navegador!!!!! Veja que o retorno do then da promise é devolvido como um retorno de função.

No Node.js já uso generators há muito tempo para combater o callback hell. E como no ES6 entrou generators, só esperar os browser suportarem e ver como o Angular suportará.

Espero ter ajudado a expandir a questão.

Ah, pode ser que eu não tenha entendido sua pergunta, aguardo seu feedback Thiago!

Acho que me expressei mal Flávio. Sei que é mais rápido mas não gosto de abrir uma função anônima com callback. A medida que o projeto vai crescendo e muitas linhas de código pra mim não fica muito legível o código.

Seria isso mesmo chamar outra função.

Faço isso em projetos usando jQuery:

    function Pagina(){};

    Pagina.prototype.run = function(){
            this.root = root;
            this.addEventListener();
      };

    Pagina.prototype.addEventListener = function(){
        ....
        botao.on('click',  $.proxy(this, 'onClickBotao'));
    };

    Pagina.prototype.onClickBotao = function(event){
           ...
      };

Gosto de criar em vários métodos minha aplicação. Evito ficar passando funções anônimas.

Mas vou dar uma olhada na documentação do promises e generators.

Entendi, claro. Eu gosto também dessa forma de organizar o código, fica mais legível. Na função construtora você pode adicionar métodos de alto nível e com nomes bem legíveis.

É que no Angular é um pouquinho diferente, no controller não é boa prática manipularmos o DOM, mas já nas diretivas você tem total poder. Não costumo fazer isso na diretiva, porque a diretiva em si seria , por analogia, igual a essa função construtora que você criou.

Enfim, acho bacana você trazer algo do seu background para dentro do Angular e unir forças. Mas mesmo na solução que você utilizou, quando for trabalhar assíncronamente com requisições ajax aninhadas, terá que passar os callback, sejam anônimos ou nomeados. É nesse contexto que falei de promise e generators apenas.