2016-02-26 16 views
6

Ho visto risposte su StackOverflow in cui le persone suggeriscono di fornire una funzione di callback a un servizio AngularJS.Perché i callback vengono promessi Metodi `.then` e Anti-Pattern

app.controller('tokenCtrl', function($scope, tokenService) { 
    tokenService.getTokens(function callbackFn(tokens) { 
     $scope.tokens = tokens; 
    }); 
}); 

app.factory('tokenService', function($http) { 
    var getTokens = function(callbackFn) { 
     $http.get('/api/tokens').then (function onFulfilled(response) { 
      callbackFn(response.data); 
     }); 
    }; 

    return { 
     getTokens: getTokens 
    }; 
}); 

Questo mi sembra un anti-pattern. Il servizio $http restituisce promesse e con i metodi .then che eseguono le funzioni di callback sembra una malsana inversione di controllo.

Come fa un codice ri-fattore come questo e come si spiega perché il modo originale era non è una buona idea?

+2

Basta dire alle persone di usare effettivamente le promesse invece di ignorarle. – SLaks

+0

Ho trovato che usare 'promise' è un po 'salutare dato che ha la capacità di incatenarlo e avere il controllo della chiamata asincrona. –

+4

Il problema principale è che con niente restituito in 'then()' non vi è alcun punto in cui richiamare errori in callback. Si rompe la catena di promessa – charlietfl

risposta

0

Il codice può essere ri-scomposto come segue:

app.controller('tokenCtrl', function($scope, tokenService) { 
    tokenService.getTokens.then (callbackFn(tokens) { 
     $scope.tokens = tokens; 
    }); 
}); 

app.factory('tokenService', function($http) { 
    var getTokens = function() { 
     //return promise 
     return $http.get('/api/tokens').then (function onFulfilled(response) { 
       //return tokens 
       return response.data; 
      } 
     ); 
    }; 

    return { 
     getTokens: getTokens 
    }; 
}); 

Avendo il servizio restituire una promessa, e utilizzando il metodo della promessa, la stessa funzionalità si ottiene con i seguenti vantaggi .then:

  • La promessa può essere salvata e utilizzata per concatenamento.

  • La promessa può essere salvata e utilizzata per evitare di ripetere la stessa chiamata $http.

  • Le informazioni di errore vengono conservate e possono essere recuperate con il metodo .catch.

  • La promessa può essere inoltrata ad altri clienti.

7

Si dovrebbe cambiare per

var getTokens = function() { 
     return $http.get('/api/tokens'); 
    }; 

E, poi in altro uso modulo

yourModule.getTokens() 
    .then(function(response) { 
    // handle it 
    }); 

Quanto al perché si tratta di un anti-modello, direi che, in primo luogo, esso doesn Ti consentono di concatenare ulteriormente i metodi di successo/fallimento del gestore. In secondo luogo, gestisce il controllo dell'elaborazione della risposta dal modulo chiamante al modulo chiamato (che potrebbe non essere super-importante qui, ma impone comunque la stessa inversione di controllo). E infine, aggiungi il concetto di promesse al tuo codice base, che potrebbe non essere così facile da capire per alcuni dei compagni di squadra, ma poi usare le promesse come callback, quindi questo non ha alcun senso.

+0

Modificato con spiegazioni, grazie) –

Problemi correlati