链接资源承诺的角度问题

时间:2015-04-29 13:50:51

标签: javascript angularjs angular-promise

我试图为我提供的这项服务链接一些承诺,但是$ stateprovider无需等待$ q即可解决。这导致我的控制器仅使用空数组返回结果对象,稍后将填充该对象。我的承诺链在哪里出错了?

我的$ stateprovider:

    .state('somestate', {
        resolve: {
            neededvalue: function(anotherservice) {
                return anotherservice.getData(); //this one works pretty well , but doesn't use any chaining
            },
            finalvalue: function(myService, neededvalue) {
                return myService.startChain(neededvalue);
            }
        }
    }

我的服务:

    app.factory("myService",
            ['$resource', '$q',
        function ($resource, $q) {

            var firstApi = $resource("api/somewhere/first", {}, { "getData": { method: "POST" } });
            var secondApi = $resource("api/somewhere/second", {}, { "getData": { method: "POST" } });

            var result = {
                array: []
            };

            var myService = {
                startChain: startChain
            };

            return myService;

            function startChain(someNeededValues) {
                var deferred = $q.defer();

                firstApi
                    .getData(someNeededValues.values).$promise
                    .then(function (data) {
                        result.value = data.value;
                    })
                    .then(recurringAction)
                    .then(deferred.resolve(result));

                return deferred.promise;
            }

            function recurringAction() {
                return secondApi.getData(result.value, function (data) {
                    angular.copy(data.array, result.array);   
                }).$promise;
            }

        }]);

3 个答案:

答案 0 :(得分:3)

不确定您的脚本是否按照您希望的方式运行deferred.resolve(result)作为回复承诺......

所以只需改变

                .then(deferred.resolve(result));

                .then(function(){
                    deferred.resolve(result)
                });

答案 1 :(得分:1)

它是{{1}}承诺

的预期行为

直接来自Angular Doc

  

重要的是要意识到调用$ resource对象方法   立即返回一个空引用(对象或数组取决于   IsArray的)。一旦数据从服务器返回现有数据   引用填充了实际数据。这是一个有用的技巧   因为通常将资源分配给当时的模型   由视图呈现。拥有一个空对象导致无法渲染,   一旦数据从服务器到达,则填充对象   随着数据和视图自动重新呈现自己显示   新数据。这意味着在大多数情况下,人们永远不必写一个   动作方法的回调函数。

答案 2 :(得分:1)

嗯,这实际上是我的一个愚蠢的错误。

我需要将deferred.resolve包装在函数内部。

    function startChain(someNeededValues) {
        var deferred = $q.defer();

        firstApi
            .getData(someNeededValues.values).$promise
            .then(function (data) {
                result.value = data.value;
            })
            .then(recurringAction)
            .then(function () {
                deferred.resolve(result);
            });

        return deferred.promise;
    }

如果没有.resolve方法可用,就像$ defer auto resolves或者其他东西。