angularjs - Isso é um "antipadrão diferido"?




angularjs-directive angularjs-service (2)

Isso é um "antipadrão diferido"?

Sim. O 'antipadrão diferido' acontece quando um novo objeto adiado redundante é criado para ser resolvido de dentro de uma cadeia de promessas . No seu caso, você está usando $ q para retornar uma promessa de algo que implicitamente retorna uma promessa. Você já possui um objeto Promise (o $http service si retorna uma promise ), portanto, basta devolvê-lo!

Aqui está o exemplo super simples de como é um serviço, com uma promessa adiada e um com antipadrão,

Isso é anti-padrão

app.factory("SomeFactory",['$http','$q']){
    return {
        getData: function(){
            var deferred = $q.defer();            
            $http.get(destinationFactory.url)
              .then(function (response) {        
                 deferred.resolve(response.data);
            })
              .catch(function (error) {
                deferred.reject(error);
            });            
            return deferred.promise;
        }
     }
}])

Isto é o que você deve fazer

app.factory("SomeFactory",['$http']){
    return {
        getData: function(){
           //$http itself returns a promise 
            return $http.get(destinationFactory.url);
        }
}

enquanto os dois são consumidos da mesma maneira.

this.var = SomeFactory.getData()
    .then(function(response) {
        //some variable = response;
    },function(response) {
        //Do error handling here
});

Não há nada de errado com os dois exemplos (pelo menos sintaticamente) .. mas o primeiro é redundante .. e não é necessário!

Espero que ajude :)

Estou achando difícil entender o "antipadrão diferido". Acho que o entendo principalmente, mas não vi um exemplo super simples de que serviço, com uma promessa diferente e um com antipadrão, então imaginei que tentaria fazer o meu, mas vendo como não sou super sabendo disso, eu gostaria de obter alguns esclarecimentos primeiro.

Eu tenho o abaixo em uma fábrica (SomeFactory):

//url = 'data.json';

return {
    getData: function(){
        var deferred = $q.defer();

        $http.get(destinationFactory.url)
            .then(function (response) {

                if (typeof response.data === 'object') {
                    deferred.resolve(response.data);
                } else {
                    return deferred.reject(response.data);
                }
            })

            .catch(function (error) {
            deferred.reject(error);
        });

        return deferred.promise;
    }

A razão pela qual estou verificando seu objeto é apenas adicionar uma camada simples de validação ao $http.get()

E abaixo, na minha diretiva:

this.var = SomeFactory.getData()
    .then(function(response) {
        //some variable = response;
    })
    .catch(function(response) {
        //Do error handling here
});

Agora, para meu entendimento, este é um antipadrão. Porque a promessa adiada original pega o erro e simplesmente o engole. Ele não retorna o erro, portanto, quando esse método "getData" é chamado, eu faço outra captura para capturar o erro.

Se esse NÃO é um antipadrão, alguém pode explicar por que ambos exigem uma espécie de "retorno de chamada"? Quando comecei a escrever esta diretiva / fábrica, previa ter que fazer uma promessa adiada em algum lugar, mas não esperava .catch() dos dois lados (ou seja, eu estava pensando que poderia conseguir que a fábrica retornasse a resposta ou o erro se eu fiz um SomeFactory.getData()


Usar o construtor $ q é um antipadrão diferido

ANTI-PADRÃO

vm.download = function() {
  var url = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf";    
  return $q(function(resolve, reject) {    
    var req = {
      method: 'POST',
      url: url,
      responseType: 'arraybuffer'
    };   
    $http(req).then(function(response) {
      resolve(response.data);
    }, function(error) {
      reject(error);
    });
  });
}

CORRIGIR

vm.download = function() {
    var url = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf";    
    var req = {
      method: 'POST',
      url: url,
      responseType: 'arraybuffer'
    };   
    return $http(req).then(function(response) {
        return response.data;
    });
}

O serviço $ http já retorna uma promessa. O uso do construtor $ q é desnecessário e propenso a erros.