在angularjs中重置$ q resolve状态

时间:2014-06-03 14:24:27

标签: javascript angularjs promise angularjs-service

我有一个运行ajax查询的服务,该查询成功转发到第二个函数以将响应解析为对象。最初调用的函数在解析promise之前使用$ q库返回一个promise,这发生在将响应解析为一个对象的第二个函数中,并将该对象作为参数传递给resolve方法。我的激活服务的控制器使用.then方法注销响应以进行测试。这一切都很有效,但是在第二次调用resolve之前,它会连续多次从初始调用返回解析。我怎样才能防止这种情况发生?

这是我的代码

app.controller("login", ['$scope','XMLMC', function ($scope,api) {
    $scope.login = function() { 
    //This is bound to an ng-click directive in the current route template
        var params = {
            selfServiceInstance: "selfservice",
            customerId: $scope.username,
            password: $scope.password
    };
        var authenticated =     api.request("session","selfServiceLogon",params).then(function(response) {
            console.log(response); 
            //log the response once the promise is resolved or rejected
        });

    };
}]);


app.factory("XMLMC", ['$http', '$q', function ($http, $q) {
    function XMLMC($http, $q) {
        $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
        var def = $q.defer();
        var P = def.promise;
        var that= this;

        this.prepareForPost = function(pkg) {
            return JSON.stringify(pkg);
        };

        this.request = function(service, request, params, host, newsession) {

            if(request === "analystLogon") {
                newsession = true;
            }

            var call = {
                service: service,
                method: request,
                params: params
            };

            if(host) {
                call.host = host;
            } else {
                call.host = "localhost";
            }

            if(newsession) {
                call.newsession = "true";
            }

            var pkg = {
                contents: this.prepareForPost(call)
            };




            $http.post('php/XMLMC/api.php', jQuery.param(pkg)).success(function (response,status) {
                    that.consume(response, def); 
                    //consume the response, pass the deferred object to resolve later

                }).error(function (response,status) {
                    def.reject(response,status);
                });

            return P; //return the promise, not the resolved object


    };

    this.consume = function(response, defer) {
        console.log(response);
        //log the response that was received.  For some reason this log happens after the log in the controller on subsequent calls to this service, not the first call.
        var resp = response[0],
            digested = {},
            i;

        digested.status = resp["attrs"]["STATUS"];
        var params = resp["children"][0]["children"];
        for(i=0; i < params.length; i++) {
            var key = params[i]["name"];
            var val = params[i]["tagData"];
            digested[key] = val;
        }

        defer.resolve(digested);
        //resolve at this point, after the response has been consumed and parsed.
    };
}

    return new XMLMC($http, $q);
    //return new instance of this object for ease of use in controller
}]);

1 个答案:

答案 0 :(得分:0)

尝试这个模式,我删除了延迟对象的创建并返回了由$ http.post启动的promise链,不确定是否会起作用但感觉应该是因为$ http会返回一个promise。

app.factory("XMLMC", ['$http', '$q', function ($http, $q) {
   function XMLMC($http, $q) {
    $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;   charset=UTF-8';

    this.prepareForPost = function(pkg) {
        return JSON.stringify(pkg);
    };

    this.request = function(service, request, params, host, newsession) {

        if(request === "analystLogon") {
            newsession = true;
        }

        var call = {
            service: service,
            method: request,
            params: params
        };

        if(host) {
            call.host = host;
        } else {
            call.host = "localhost";
        }

        if(newsession) {
            call.newsession = "true";
        }

        var pkg = {
            contents: this.prepareForPost(call)
        };




        return $http.post('php/XMLMC/api.php', jQuery.param(pkg))
       .then(that.consume)

};

consume = function(response) {
    console.log(response);
    var resp = response[0],
        digested = {},
        i;

    digested.status = resp["attrs"]["STATUS"];
    var params = resp["children"][0]["children"];
    for(i=0; i < params.length; i++) {
        var key = params[i]["name"];
        var val = params[i]["tagData"];
        digested[key] = val;
    }

    return $q.resolve(digested);
    //resolve at this point, after the response has been consumed and parsed.
};

}

return new XMLMC($http, $q);
//return new instance of this object for ease of use in controller

}]);