promises - then catch angularjs




¿Es este un "antipatrón diferido"? (2)

Me resulta difícil entender el "antipatrón diferido". Creo que lo entiendo en principio, pero no he visto un ejemplo súper simple de lo que es un servicio, con una promesa diferente y una con antipatrón, así que pensé que trataría de hacer la mía, pero viendo que no súper al respecto, primero obtendría algunas aclaraciones.

Tengo lo siguiente en una 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;
    }

La razón por la que estoy comprobando que es un objeto es solo para agregar una capa simple de validación en $http.get()

Y a continuación, en mi directiva:

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

Ahora, para mi comprensión, este es un antipatrón. Porque la promesa diferida original capta el error y simplemente se lo traga. No devuelve el error, así que cuando se llama a este método "getData", tengo que hacer otra captura para obtener el error.

Si esto NO es un antipatrón, ¿alguien puede explicar por qué ambos requieren una especie de "devolución de llamada"? Cuando comencé a escribir esta fábrica / directiva, anticipé tener que hacer una promesa diferida en alguna parte, pero no .catch() tener que .catch() en ambos lados (también estaba pensando que podría hacer que la fábrica devolviera la respuesta o el error si hice un SomeFactory.getData()


¿Es este un "antipatrón diferido"?

Sí lo es. El 'antipatrón diferido' ocurre cuando se crea un nuevo objeto diferido redundante para ser resuelto desde dentro de una cadena de promesa . En su caso, está utilizando $ q para devolver una promesa para algo que implícitamente devuelve una promesa. Ya tiene un objeto Promesa (el $http service sí mismo devuelve una promise ), ¡así que solo necesita devolverlo!

Aquí está el ejemplo súper simple de lo que es un servicio, con una promesa diferida y una con aspecto antipatrón,

Esto es antipatrón

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;
        }
     }
}])

Esto es lo que debes hacer

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

mientras que ambos se consumen de la misma manera.

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

No hay nada malo con ninguno de los ejemplos (al menos sintácticamente) ... pero el primero es redundante ... ¡y no es necesario!

Espero eso ayude :)


Usar el constructor $ q es un antipatrón diferido

ANTI-PATRÓN

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);
    });
  });
}

CORRECTO

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;
    });
}

El servicio $ http ya devuelve una promesa. Usar el constructor $ q es innecesario y propenso a errores.







angular-promise