【问题标题】:AngularJS $http result with promiseAngularJS $http 结果与承诺
【发布时间】:2015-11-29 16:05:13
【问题描述】:

我是 angular $q 服务的新手。我正在使用 $http 和 angular $q 服务来实现异步请求。下面是我的代码,我无法获得后端 api 的结果。 (json)

Services.js

.service('httpService', function($q, $http, $timeout) {

 var asyncRequest = function(url) {
    return $http.get(url)
        .then(function(response) {
            //res is the index of an array in php, which will be encoded.
            return response.res;

        }, function(response) {
            // something went wrong
            return $q.reject(response.res);
        });
 };
 return {
   asyncRequest : asyncRequest 
 };

});

Controller.js

var result = httpService.test(url)
.then(function(data) {
    // Line below gives me "undefined"
    console.log(data);
}, function(error) {
    alert("Error...!");
});

提到的行,给我未定义。 (当然,我可以在main函数中写console.log(data),但这不是一个好习惯,因为我想将result返回给controller

关于我的$q服务的实现,有没有更简单的方法?

任何想法将不胜感激。

【问题讨论】:

  • 应该是response.data,而不是response.res。如果res 是服务器返回的响应数据对象的索引,则只需返回response.data.res
  • @ryeballar 是的,您的笔记和西蒙的回答相结合,是正确的解决方案。谢谢大家。

标签: javascript angularjs asynchronous q angular-promise


【解决方案1】:

您应该在这种情况下使用$q,因为$http 已经返回了一个承诺。将 2 一起使用效率低下。 ($q 在您使用非角度异步函数时很有用,例如 Geo 查找)。

Services.js:

.service('httpService', function($http, $timeout) {

  var asyncRequest = function(url) {
    return $http.get(url)
  };
  return {
   asyncRequest : asyncRequest 
  };

});

Controller.js:

var result = httpService.asyncRequest(url)
.then(function(res) {
    console.log(res.data);
}, function(error) {
    alert("Error...!");
});

【讨论】:

  • 非常感谢。还有一个问题。我怎样才能让它嵌套?我的意思是另一个$http 取决于第一个的结果。
【解决方案2】:

第一件事是您使用的是工厂风格而不是服务。 service 只是一个函数,其中方法在this 参考上定义。

我认为你不需要在服务中使用.then 只需返回 $http 返回的承诺

app.service('httpService', function($q, $http, $timeout) {

  this.asyncRequest = function(url) {
    return $http.get(url);
  };
});

在控制器中

 var result = httpService.test(url)
  .then(function(res) {
    // Line below gives me "undefined"
    console.log(res.data);
  }, function(error) {
    alert("Error...!");
  });

【讨论】:

    【解决方案3】:

    我认为您在服务中使用了 at factory 的语法。

    .service('httpService', function($q, $http, $timeout) {
       this.asyncRequest = function(url) {};
    });
    

    .factory('httpService', function($q, $http, $timeout) {
       return {asyncRequest: function(url) {}};
    });
    

    【讨论】:

      【解决方案4】:

      响应已在上述行中被拒绝。你不需要拒绝其他任何事情。所以你不需要$q

      首先你已经返回了一个承诺。您可以在控制器中通过添加 $http 承诺的 success()error() 代表来处理它。 其次,这是异步操作。而且您无法从成功回调中返回响应,例如jQuery.ajax()。这不是同步调用,这是异步调用,您必须使用回调。你的错误就在这里。当响应将被解决或拒绝时,只需返回承诺并在控制器中处理它。

      所以你的控制器代码可以是这样的:

      httpService.asyncRequest({
          ...
      }).success(function(successfulResponse) {
          ...
      }).error(function(failedResponse) {
          ...
      });
      
      【解决方案5】:
      .service('httpService', function($q, $http, $timeout) {
      
       var asyncRequest = function(url) {
         var defer = $q.defer();
          return $http.get(url)
              .then(function(response) {
                  //res is the index of an array in php, which will be encoded.
                  defer.resolve(response);
      
              }, function(response) {
                  // something went wrong
                  defer.reject(response.res);
              });
           return defer.promise;
       };
       return {
         asyncRequest : asyncRequest 
       };
      
      });
      

      你应该像这样从你的对象中返回承诺

      【讨论】:

      • @Bergi BTW 我没有复制你的答案。我在我的项目中使用了很多类似的服务。还有一件事我的回答与您在链接中提到的不同。我的代码中没有任何 catch 块。无论如何,我尊重社区和所有像你一样受人尊敬的成员。因此,如果我的回答被您否决,那就没有问题了。
      • 答案的副本?不,我要说的是“你应该不要从这样的对象返回promise”。在这里使用.then(…, …) instead of .then(…).catch(…) 是可以的,但没有区别,它仍然是延迟的反模式。
      • 顺便说一句,我什至没有投反对票,是另外 5 个人,其中一些人似乎同意我的观点。
      猜你喜欢
      • 1970-01-01
      • 2016-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多