当第二个查询依赖于第一个查询的结果时,我如何等待两个查询?



我试图从不同的数据库获得两个结果集。第二个结果取决于从第一个结果集中检索到的参数。我想确保在继续之前返回两个结果集。看到其他一些问题,我想也许这样可以:

app.factory('myService',['$http','$q',function ($http, $q){
        function getDetails(scope){
            var paths = [];
            return $q.all([
                $http.post('getdetails.php',{begDate:scope.begDate, endDate:scope.endDate})
                .then(function(response) {
                     angular.forEach(response.data,function(table,key){
                        angular.forEach(table, function(row,key){
                            paths.push(row.CURRENT_PATH);
                        })
                     })
                     return response;
                 })
            ,
                $http.post('coordtest.php', {paths: paths})
                .then(function(response) {
                    return response;
                })
            ]);
        }
        return {
            getDetails: getDetails
        };
}]);

但是结果都得到返回,而路径仍然是空的?

看起来好像在从第一个请求中检索数据之前无法发出第二个请求。但是,您希望返回第二个请求的承诺。这是可能的,但是$q.all不是很适合(它对于可以一次发送所有请求的场景更有用)。

你似乎实际上是让一个请求(B)依赖于另一个请求(A)的结果,但要返回B的承诺,以便它的结果可以使用。这可以使用$q.defer使用以下模式创建包装器承诺:

var response = $q.defer();
$http.get('a').success(function(data){
    $http.get('b', data).then(response.resolve, response.reject);
});
return response.promise;
在您的代码中,这可能看起来像:
app.factory('myService',['$http','$q',function ($http, $q){
    function httpGetDetails(scope){
        return $http.post('getdetails.php',{
            begDate:scope.begDate, 
            endDate:scope.endDate
        });
    }    
    function parseDetails(response){
        return response.reduce(function(parsedResults, table){
            var paths = table.map(function(row){
                return row.CURRENT_PATH;
            });
            return parsedResults.concat(paths);
        }, []);
    } 
    function getDetails(scope){
        var result = $q.defer();
        var getDetailsRequest = httpGetDetails(scope);
        getDetailsRequest.success(function(response){
            var paths = parseDetails(response);
            $http.post('coordtest.php', {paths: paths})
                   .success(result.resolve) // Both requests succeeded
                   .error(result.reject);  // coordtest.php failed
        });
        // getdetails.php failed. 
        // Consider sending params that make it more obvious which failed
        getDetailsRequest.error(result.reject);
        return result.promise;
    }
    return {
        getDetails: getDetails
    };
}]);

显然,您可以稍微清理一下函数,但这是链接承诺的一个简单要点。

这个想法是你创建一个更长的运行承诺,并根据内部(第二个)请求的结果手动解析它。这类似于从您的myService工厂返回coordtest响应,除了它是可行的(您不能同步返回在异步函数中做出的$http承诺,因此您可以做并提前创建屏蔽承诺)。

最新更新