【问题标题】:AngularJS: Returning a promise from within .then?AngularJS:从.then 内部返回一个承诺?
【发布时间】:2016-08-31 05:59:19
【问题描述】:

我有一个用户服务。我想创建一个利用我建立的另一个服务的方法。此服务有两种方法。 getUser()getCurrentUser()getCurrentUser() 使用获取 UID 的注入服务。它使用返回的 UID 来运行 getUser() 方法。我的问题是我无法让getCurrentUser() 返回第二层承诺。

这个问题有点难以解释。这是代码...

svs.service("usersService", function($rootScope, $http, loginService, alertBoxService) {
  var self = this;
  self.getUser = function(identifier, column) {
    if (typeof(column) === 'undefined') column = "uid";
    return $http.get($rootScope.api + "/getUser/" + identifier + "/" + column);
  }
  self.getCurrentUser = function() {
    var currentUserPromise;
    loginService.getCurrentUid().then(
      function(response) {
        if (response.data === "false") {
          alertBoxService.trigger($rootScope.unexpectedApiResponse);
        } else {
          console.log(self.getUser(response.data));
          currentUserPromise = self.getUser(response.data);
        }
      }, function(response) {
        alertBoxService.trigger($rootScope.asyncFailed);
      }
    );
    return currentUserPromise;
  }
});

【问题讨论】:

标签: javascript angularjs nested promise resolve


【解决方案1】:

链接承诺,但不要忘记链接拒绝...

self.getCurrentUser = function() {
    return loginService.getCurrentUid().then(function(response) {
        if (response.data === 'false') {
            alertBoxService.trigger($rootScope.unexpectedApiResponse);
            return $q.reject(response); // convert into a rejection
        }
        return self.getUser(response.data); // chain the promise resolution
    }, function(response) {
        alertBoxService.trigger($rootScope.asyncFailed);
        return $q.reject(response); // chain the rejections
    });
}

您当然需要注入$q 服务。


作为Bergi kindly pointed out,你也可以通过抛出错误来拒绝承诺,而不是使用$q.reject,例如

throw response;

【讨论】:

  • 您可能还想突出显示第一个添加的return,了解then的人很容易忘记它
  • 我们在这里用$q 做什么?
  • 不使用$q.reject,你可以直接rethrow这个错误。
  • @Allenph 当通过thencatch 的第二个参数处理承诺拒绝时,除非该处理程序返回被拒绝的承诺或抛出错误,否则它将转换为已解决的承诺。这让上游消费者知道承诺被拒绝。否则,他们会认为它成功了。
  • @Allenph …并以 undefined 作为履行值成功,这可能是意外并导致下游进一步异常。
【解决方案2】:

这里的问题是当函数getCurrentUser被调用时,它立即返回一个undefined变量。这是因为服务是异步的,当服务收到响应时,函数调用已经返回了一个undefined 变量。为了防止这种情况,您可以在loginService 中添加return 调用。

【讨论】:

    【解决方案3】:

    要让异步函数从成功回调中返回承诺,您必须从回调(即承诺对象)返回,然后从主函数返回,以便向调用者提供承诺。

    试试这个。

      svs.service("usersService", function($rootScope, $http, loginService, alertBoxService) {
      var self = this;
      self.getUser = function(identifier, column) {
        if (typeof(column) === 'undefined') column = "uid";
        return $http.get($rootScope.api + "/getUser/" + identifier + "/" + column);
      }
      self.getCurrentUser = function() {
        return loginService.getCurrentUid().then(
          function(response) {
            if (response.data === "false") {
              alertBoxService.trigger($rootScope.unexpectedApiResponse);
            } else {
              console.log(self.getUser(response.data));
              return self.getUser(response.data);
            }
          }, function(response) {
            alertBoxService.trigger($rootScope.asyncFailed);
          }
        );
      }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-09
      • 2018-03-10
      • 1970-01-01
      • 2016-03-21
      • 2015-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多