AngularJS:为什么.then()不等待promise对象到达

时间:2015-09-22 13:33:38

标签: javascript angularjs angular-services

为了进行API调用,我创建了以下角度服务。

(function (module) {
    module.service('APIService',function ($http, $q) {
        console.log("Reached APIService")
        var deferred = $q.defer();
        this.getData = function (requestURL) {
            console.log("Reached APIService @GET", requestURL);
            $http.get(requestURL).success(
                function (data, status) {
                    deferred.resolve(data);
                    console.log("In service",status,data);
                }).error(
                function (data, status) {
                    deferred.reject(data);
                    console.log(status);
                });
            return deferred.promise;
        };

        this.postData = function (requestURL, requestObj) {
            console.log("Reached APIService @POST", requestURL, requestObj);
            $http.post(requestURL, requestObj).success(
                function (data, status) {
                    deferred.resolve(data);
                    console.log(status);
                }).error(
                function (data, status) {
                    deferred.reject(data);
                    console.log(status);
                });
            return deferred.promise;
        };
    });
}(angular.module("MainApp")));

我已将它注入我的两个控制器中。但是,我面临以下问题:

  1. 当我第一次在第一个控制器中调用它时,它工作正常并返回所需的结果。但是,当我在第二个控制器中调用它时如下:

        APIService.getData(Config + headerURL).then(function (response) {
            console.log(Config + headerURL);
            console.log("header response from API", response);
    
        },function(error) {
            console.log("API call for header data failed");
        });
    
  2. 由于我的服务返回一个promise对象,我不希望.then()内的代码在服务数据到达之前工作。  但是,它在服务数据到达之前运行(不知道如何)。最奇怪的是,我进入.then()的响应实际上并不是来自此URL的响应(Config + headerURL),而是从先前在第一个使用相同的控制器中调用的不同URL获得的响应APIService服务。

    告知:当前网址的实际响应确实会在稍后阶段到达。

    我知道异步调用,我认为在这种情况下它有一些事情要做,但我想.then()在Angular中处理它。所以我很困惑这里的问题是什么。请问有人可以解决一些问题吗?

4 个答案:

答案 0 :(得分:2)

由于服务是单例,因此您只有一个延迟对象的实例。

一旦解决,它将继续被解析,所以下次你调用getData时,它会立即返回。

你可以搬家:

var deferred = $q.defer();

在你的getData和postData函数中。

或者您可以返回$ http创建的承诺。

答案 1 :(得分:1)

试试这个,你需要return到http结果。

this.getData = function (requestURL) {
            console.log("Reached APIService @GET", requestURL);
           return $http.get(requestURL) };

答案 2 :(得分:0)

看起来你必须在$ http call中显式禁用缓存。

$http.get({
  url: requestURL,
  cache: false
})

答案 3 :(得分:0)

$http已经返回承诺时,您通过创建自己的承诺来使用反模式

在此服务中完全摆脱$q,只需返回$http

即可
this.getData = function (requestURL) {
    console.log("Reached APIService @GET", requestURL);
    return $http.get(requestURL).then(function (response) {
        return response.data;
        console.log("In service", status, data);
    }, function () {
        // errror handling here
    });

};