AngularJS : Où utiliser promesses?
J'ai vu quelques exemples de Facebook Login services qui ont été à l'aide de promesses pour accéder à FB API Graphique.
Exemple #1:
this.api = function(item) {
var deferred = $q.defer();
if (item) {
facebook.FB.api('/' + item, function (result) {
$rootScope.$apply(function () {
if (angular.isUndefined(result.error)) {
deferred.resolve(result);
} else {
deferred.reject(result.error);
}
});
});
}
return deferred.promise;
}
Et services utilisés "$scope.$digest() //Manual scope evaluation"
quand eu la réponse
Exemple #2:
angular.module('HomePageModule', []).factory('facebookConnect', function() {
return new function() {
this.askFacebookForAuthentication = function(fail, success) {
FB.login(function(response) {
if (response.authResponse) {
FB.api('/me', success);
} else {
fail('User cancelled login or did not fully authorize.');
}
});
}
}
});
function ConnectCtrl(facebookConnect, $scope, $resource) {
$scope.user = {}
$scope.error = null;
$scope.registerWithFacebook = function() {
facebookConnect.askFacebookForAuthentication(
function(reason) { //fail
$scope.error = reason;
}, function(user) { //success
$scope.user = user
$scope.$digest() //Manual scope evaluation
});
}
}
Les questions sont:
- Quel est le différence dans les exemples ci-dessus?
- Quels sont les raisons et cas à utiliser $q service?
- Et comment est-il travail?
- on dirait que vous devriez lire sur ce que sont les promesses, et pourquoi ils sont utilisés en général... ils ne sont pas exclusifs à angulaires et il y a beaucoup de matériel disponible
- bon point, mais je m'attendais à une réponse complexe qui permettra de couvrir à la fois: pourquoi ils sont utilisés en général et comment l'utiliser dans Angulaire. Merci pour votre suggestion
Vous devez vous connecter pour publier un commentaire.
Ce n'est pas une réponse complète à votre question, mais j'espère que cela va vous aider, vous et d'autres personnes lorsque vous essayez de lire la documentation sur le
$q
service. Il m'a fallu un certain temps pour le comprendre.Laissons de côté AngularJS pour un moment, et il suffit de considérer le Facebook des appels d'API. À la fois les appels d'API utiliser un rappel mécanisme pour informer l'appelant lorsque la réponse de Facebook est disponible:
C'est un modèle standard pour la manipulation des opérations asynchrones en JavaScript et d'autres langages.
Un gros problème avec ce modèle se pose lorsque vous avez besoin pour effectuer une séquence d'opérations asynchrones, où chaque opération dépend du résultat de l'opération précédente. C'est ce que ce code est fait:
D'abord, il essaie de se connecter, puis seulement après avoir vérifié que la connexion a réussi t-il en faire la demande à l'API Graphique.
Même dans ce cas, qui est le seul à enchaîner deux opérations, les choses commencent à déraper. La méthode
askFacebookForAuthentication
accepte un rappel de l'échec et de la réussite, mais ce qui arrive quandFB.login
réussit, maisFB.api
échoue? Cette méthode appelle toujours lesuccess
rappel quel que soit le résultat de laFB.api
méthode.Maintenant, imaginez que vous êtes en train de coder un robuste séquence de trois ou plus des opérations asynchrones, d'une manière qui gère correctement les erreurs à chaque étape et sera lisible pour quelqu'un d'autre ou même après quelques semaines. Possible, mais il est très facile de simplement continuer à la nidification de ces rappels et de perdre la trace des erreurs le long du chemin.
Maintenant, laissons de côté l'Facebook API, pour un moment, et il suffit de considérer l'angle de Promesses API, mis en place par le
$q
service. Le modèle mis en œuvre par ce service est une tentative de tourner la programmation asynchrone en arrière en quelque chose ressemblant à une série linéaire de déclarations simples, avec la possibilité de lancer une erreur à n'importe quelle étape de la voie et de le traiter à la fin, sémantiquement similaire à l'familiertry/catch
bloc.Considérer cet exemple artificiel. Disons que nous avons deux fonctions, d'où la deuxième fonction qui consomme le résultat de la première:
Maintenant, imaginez que firstFn et secondFn ont tous deux une longue période de temps, si l'on veut traiter cette séquence de façon asynchrone. Nous avons d'abord créer un nouveau
deferred
objet, ce qui représente une chaîne d'opérations:La
promise
propriété représente le résultat final de la chaîne. Si vous vous connectez une promesse immédiatement après la création, vous allez voir que c'est juste un objet vide ({}
). Rien à voir pourtant, aller à droite le long.Jusqu'à présent notre promesse ne représente que le point de départ de la chaîne. Maintenant, nous allons ajouter nos deux opérations:
La
then
méthode ajoute une étape à la chaîne et renvoie une nouvelle promesse représentant le résultat final de l'extension de la chaîne. Vous pouvez ajouter autant d'étapes que vous le souhaitez.Jusqu'à présent, nous avons mis en place notre chaîne de fonctions, mais rien de ce qui s'est réellement passé. Vous obtenez les choses ont commencé par l'appel de
deferred.resolve
, en spécifiant la valeur initiale que vous souhaitez passer à la première étape de la chaîne:Et puis...toujours rien ne se passe. Pour s'assurer que les changements de modèle sont bien suivies, Angulaire n'a pas fait appel de la première étape de la chaîne jusqu'à la prochaine fois
$apply
est appelé:Ainsi que sur la gestion des erreurs? Jusqu'à présent, nous avons seulement indiqué une gestionnaire de succès à chaque étape de la chaîne.
then
accepte également un gestionnaire d'erreur, comme un deuxième argument optionnel. En voici un autre, plus l'exemple d'une promesse de la chaîne, cette fois avec la gestion des erreurs:Comme vous pouvez le voir dans cet exemple, chaque gestionnaire de la chaîne a l'occasion de détourner le trafic vers la prochaine erreur gestionnaire au lieu de la prochaine succès gestionnaire. Dans la plupart des cas, vous pouvez avoir un seul gestionnaire d'erreur à la fin de la chaîne, mais vous pouvez aussi avoir l'intermédiaire des gestionnaires d'erreur que la tentative de récupération.
Pour revenir rapidement à vos exemples et vos questions), je vais juste dire qu'elles représentent deux manières différentes pour s'adapter Facebook callback de l'API orientée Angulaire de la voie de l'observation des changements de modèle. Le premier exemple encapsule l'appel d'API en une promesse, qui peut être ajouté à un champ d'application et est entendu par Angulaire du système de template. Le second prend le plus de force brute approche de définition de la fonction de rappel directement le résultat sur le champ, puis en appelant
$scope.$digest()
de faire Angulaire au courant du changement à partir d'une source externe.Les deux exemples ne sont pas directement comparables, car la première est manquant, l'étape de connexion. Cependant, il est généralement souhaitable d'encapsuler les interactions avec les Api externe de ce genre dans des services distincts, et d'envoyer les résultats aux contrôleurs que des promesses. De cette façon, vous pouvez garder vos contrôleurs séparés de préoccupations externes, et de les tester plus facilement avec des simulations de services.
then
méthodes est d'utiliser$q.all
. Un rapide tutoriel sur la qui peut être trouvé ici.$q.all
est appropriée si vous avez besoin d'attendre plusieurs indépendant opérations asynchrones complète. Il ne remplace pas le chaînage si chaque opération dépend du résultat de l'opération précédente.return 'firstResult'
partie dereturn $q.resolve('firstResult')
, quelle sera la différence?C'est le plunk pour angulaire promesses MVP (minimum viable promesse): http://plnkr.co/edit/QBAB0usWXc96TnxqKhuA?p=preview
Source:
(pour ceux qui ont la flemme de cliquer sur les liens)
index.html
app.js
(Je sais ça ne résout pas votre Facebook exemple mais je trouve les extraits suivants utiles)
Via: http://markdalgleish.com/2013/06/using-promises-in-angularjs-views/
Mise à jour le 28 Février 2014: de 1.2.0, les promesses ne sont plus résolu par des modèles.
http://www.benlesh.com/2013/02/angularjs-creating-service-with-http.html
(plunker exemple utilise 1.1.5.)
Un différé représente le résultat d'une opération asynchrone. Il expose une interface qui peut être utilisée pour la signalisation de l'état et le résultat de l'opération qu'elle représente. Il fournit également un moyen d'obtenir la promesse de l'instance.
Une promesse fournit une interface pour interagir avec il est différé, et donc, permet aux parties intéressées d'avoir accès à l'état et à la suite de l'opération différée.
Lors de la création d'un différé, c'est l'état est en attente et il n'a pas de résultat. Lorsque nous résoudre (ou de rejeter) le report de la, il change d'état à résoudre ou rejeté. Néanmoins, nous pouvons obtenir la promesse immédiatement après la création d'un reportés et même affecter les interactions avec elle l'avenir du résultat. Ces interactions ne se feront qu'après le différé rejeté ou de les résoudre.
utilisation promesse au sein d'un contrôleur et vérifiez que les données sont disponibles ou pas
JS:
HTML: