Intereting Posts

Enchaînement des promesses de promesses angulaires

J'ai une promesse enchaînée et, dans le cas d'un rejet pour l'une ou l'autre des promesses, je dois effectuer une opération asynchrone (obtenir le message d'erreur traduit). Comme j'avais déjà une promesse enchaînée pour réussir, je suppose qu'il n'est pas possible de faire appel au rejet. Je tente simplement de nicher les appels asynchrones, mais je n'abandonne pas la promesse résolue de deferred.reject(deferredRejection.promise); au dessous de. Des pointeurs appréciés!

 login: function(email, password) { var deferred = $q.defer(); AuthService.login(email, password).then(function(response) { var user = { 'accountToken': response.accountToken, 'email': response.username, 'onboarded': response.onboarded, 'verified': response.verified }; return SyncStorageService.write(SyncStorageService.storageKeys.user, user); }, function(error) { // login failed var deferredRejection = $q.defer(); $translate('ALERTS.LOGIN_FAILED').then(function(translatedValue) { deferredRejection.resolve(translatedValue); }); deferred.reject(deferredRejection.promise); }).then(function(data) { deferred.resolve(data); }, function(error) { // saving data failed var deferredRejection = $q.defer(); $translate('ALERTS.UNKNOWN').then(function(translatedValue) { deferredRejection.resolve(translatedValue); }); deferred.reject(deferredRejection.promise); }); return deferred.promise; } 

Solution mise à jour:

Sur la base de la réponse ci-dessous, j'ai réécrit le code comme suit:

 login: function(email, password) { return AuthService.login(email, password).then(function(response) { return { 'accountToken': response.accountToken, 'email': response.username, 'onboarded': response.onboarded, 'verified': response.verified }; }).then(function(data) { return SyncStorageService.write(SyncStorageService.storageKeys.user, data); }); } 

Remarques:

  • AuthService.login et SyncStorageService.write rejettent maintenant les promesses avec un objet d' Error (par exemple, une new Error('ALERT.ERROR_MESSAGE'); ), qui se new Error('ALERT.ERROR_MESSAGE'); par la login au contrôleur (précédemment faisait la traduction au niveau du service);
  • Le contrôleur qui appelle la méthode de login a les .then() et .catch() – sur un .catch (), le Error.message passé est traduit et affiché.

    Il semble que vous ne promettez pas vraiment, et que vous utilisez la promesse oubliée / l'anti-modèle différé . En formulant quelques hypothèses sur la façon dont vous voulez vraiment que cela se comporte, et en prenant en considération les appels à $translate , alors quelque chose comme le suivant, je soupçonne, c'est ce que vous attendez:

     login: function(email, password) { return AuthService.login(email, password).then(function(response) { return { 'accountToken': response.accountToken, 'email': response.username, 'onboarded': response.onboarded, 'verified': response.verified }; }, function() { return $q.reject('ALERTS.LOGIN_FAILED'); }).then(function(user) { return SyncStorageService.write(SyncStorageService.storageKeys.user, user).catch(function() { return $q.reject('ALERTS.UNKNOWN'); }); }).catch(function(message) { return $translate(message).then(function(translatedValue) { return $q.reject(translatedValue); }); }); } 

    Les principales choses à garder à l'esprit sont:

    • Si vous désirez définitivement rejeter la promesse dérivée, renvoyez $q.reject(error) du retour $q.reject(error) retour ou d'erreur.

      Tous les rappels d'erreur ci-dessus font ceci. Ceux qui ont tenté la connexion ou la sauvegarde utilisent la clé de traduction comme l'erreur qui sera finalement transmise au rappel final des catch . Le rappel de succès de $translate également cela pour transformer sa promesse résolue en une rejetée, de sorte que le rapprochement final des retours renvoie une promesse rejetée, de sorte que le code d'appel obtient une promesse rejetée et (vraisemblablement) montre l'erreur traduite pour l'utilisateur.

    • Si vous voulez absolument résoudre la promesse dérivée, renvoyer tout ce qui n'est pas une promesse de succès ou de rappel d'erreur. La promesse dérivée sera résolue avec cette valeur. (Cela inclut undefined si vous n'avez pas de valeur de retour explicite).

      C'est ce qui est fait ci-dessus lors du retour du retour de l'utilisateur return {'accountToken'.... dans le premier rappel.

    • Si vous souhaitez différer la résolution / rejet d'une promesse, renvoyer une autre promesse du rappel de réussite ou d'erreur. Ensuite, la promesse dérivée sera finalement résolue ou rejetée de la manière que cette autre promesse soit résolue ou rejetée.

      C'est ce qui se fait plus haut lorsque vous retournez SyncStorageService.write... et lorsque vous retournez $translate(... .