为什么我从http服务中得到未定义?

时间:2017-07-30 09:47:26

标签: angularjs

我使用$ q创建$ http服务。

这是我的$ http服务:

function dashboardService($http, $log, $q, config) {

    var service = {
        getClientId: getClientIDByLayout,
    };

    return service;

    function getClientIDByLayout(layoutId) {
        var deferred = $q.defer();
        return $http.get(config.baseUrl + "api/ClientLayoutMercator?layoutId=" + layoutId).then(function (result) {
            deferred.resolve(result.data);
        }, function (result) {
            deferred.reject(result);
        });

        return deferred.promise;
    }  
}

以下是我在控制器内部调用服务的方式:

  dashboardService.getClientId(layoutId).then(function (data) {
      var t = data;//undifined
   });

但我在var t = data行中得到的结果是undefined

知道为什么我从服务中得到未定义的内容?

2 个答案:

答案 0 :(得分:3)

基本上你的getClientIDByLayout函数中有两个return语句,两者都返回promise本身。正如我在您当前的实施中所看到的,您正在创建新的promise&手动管理拒绝/解决。但问题是第一个返回语句(return $http.get()使其他返回语句(return deferred.promise)变得多余。因此,第一个承诺从控制器返回订阅。最终$http.get不会返回任何内容,因此您在successCallback中获得undefined

您可以通过删除1st return语句轻松解决此问题,如下所示。

function getClientIDByLayout(layoutId) {
    var deferred = $q.defer();
    //removed `return` from below code.
    $http.get(config.baseUrl + "api/ClientLayoutMercator?layoutId=" + layoutId).then(function (result) {
        deferred.resolve(result.data);
    }, function (result) {
        deferred.reject(result);
    });
    //custom promise should get return 
    return deferred.promise;
}  

理想情况下创建被视为反模式的承诺开销,而不是$http.get返回的承诺。只需从成功回调中返回一个数据就可以实现承诺。

<强>代码

function getClientIDByLayout(layoutId) {
    ̶v̶a̶r̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶ ̶=̶ ̶$̶q̶.̶d̶e̶f̶e̶r̶(̶)̶;̶
    return $http.get(config.baseUrl + "api/ClientLayoutMercator?layoutId=" + layoutId)
      .then(function (result) {
         //returning data from promise, it will provide it to subsequent `.then`
         return result.data;
      }, function (error) {
         ͟r͟e͟t͟u͟r͟n͟ $q.reject(error);
      }
    );
}  

答案 1 :(得分:1)

而不是$q.defer,只需returnthrow .then方法中的处理函数:

function dashboardService($http, $log, ̶$̶q̶,̶ config) {

    var service = {
        getClientId: getClientIDByLayout,
    };

    return service;

    function getClientIDByLayout(layoutId) {
         ̶v̶a̶r̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶ ̶=̶ ̶$̶q̶.̶d̶e̶f̶e̶r̶(̶)̶;̶
        return $http.get(config.baseUrl + "api/ClientLayoutMercator?layoutId=" + layoutId).then(function (result) {
            ̶d̶e̶f̶e̶r̶r̶e̶d̶.̶r̶e̶s̶o̶l̶v̶e̶(̶r̶e̶s̶u̶l̶t̶.̶d̶a̶t̶a̶)̶;̶ 
            return result.data;
        }, function (result) {
            ̶d̶e̶f̶e̶r̶r̶e̶d̶.̶r̶e̶j̶e̶c̶t̶(̶r̶e̶s̶u̶l̶t̶)̶;̶ 
            throw result;
        });

        ̶r̶e̶t̶u̶r̶n̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶.̶p̶r̶o̶m̶i̶s̶e̶;̶
    }  
}

.then方法返回新承诺,通过successCallbackerrorCallback的返回值解析或拒绝(除非该值是承诺) ,在这种情况下,使用promise chaining)解析该承诺中解决的值。 1

错误地使用包含缺少returnthrow语句的功能的then方法返回承诺,该服务是返回一个解析为undefined的承诺。

有关详细信息,请参阅You're Missing the Point of Promises