首页 文章

链接Angular承诺拒绝

提问于
浏览
0

我有一个链式承诺,如果拒绝任何一个承诺,我需要执行异步操作(获取翻译的错误消息) . 因为我不能在拒绝时链接 - 我试图简单地嵌套异步调用,但是我没有从下面的 deferred.reject(deferredRejection.promise); 获得已解决的承诺 . 指针赞赏!

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

Updated Solution:

根据下面的答案,我能够重新编写代码如下:

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

笔记:

  • AuthService.loginSyncStorageService.write 现在都拒绝承诺 Error 对象(例如 new Error('ALERT.ERROR_MESSAGE'); ),它通过 login 向控制器冒泡(以前在服务级别进行翻译);

  • 调用 login 方法的控制器具有 .then().catch() 块 - 在.catch()上,传递的 Error.message 被翻译并显示 .

1 回答

  • 2

    看起来你并没有真正链接承诺,而是使用the forgotten promise/deferred anti pattern . 做一些关于你实际上希望它如何表现的假设,并将对 $translate 的调用分解出来,那么下面我怀疑的是你所追求的:

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

    要记住的主要事项是:

    • 如果您肯定要拒绝派生的promise,请从成功或错误回调中返回 $q.reject(error) .

    上面的所有错误回调都是这样做的 . 尝试登录或保存后的那些使用翻译密钥作为最终将传递给最终 catch 回调的错误 . 来自 $translate 的成功回调也会将其解析后的承诺转换为被拒绝的承诺,因此最终的catch回调会返回被拒绝的承诺,因此调用代码会获得被拒绝的承诺,并且(可能)会向用户显示已翻译的错误 .

    • 如果您肯定想要解决派生的promise,请从成功或错误回调中返回任何非承诺的内容 . 派生的承诺将使用该值解决 . (如果您没有明确的返回值,则包括 undefined ) .

    这是在第一次回调中返回用户 return {'accountToken'.... 时执行的操作 .

    • 如果要推迟解析/拒绝承诺,请从成功或错误回调中返回另一个承诺 . 然后,最终解决或拒绝派生的承诺,无论以何种方式解决/拒绝其他承诺 .

    这是在返回 SyncStorageService.write... 时以及返回 $translate(... 时执行的操作 .

相关问题