AngularJS:如何运行具有依赖项的函数

时间:2017-09-19 17:42:05

标签: javascript angularjs

如何运行函数" searchBoats"当这两个函数调用promise方法时,当这两个参数作为AngularJS中先前函数的结果返回时,有两个参数?

var parseURL = function() {                         
    var language = $routeParams.language;                           
    var url = $location.path(); 
    boatType = parseBoatType(url, language);
    var destination = parseDestination(url, language);
    searchBoats(destination, boatType);                                                                 };      

    parseURL();

    var parseBoatType = function(url, language) {
        var boatType = UrlService.parseUrlBoatType(url, language);                                      

        var boatTypeParsed = UrlService.parseBoatType(url, language);           

        // boat type is parsed
        if(boatTypeParsed) {
            BoatType.getBoatTypeByName({name: boatTypeParsed}, function success(result) {
                boatTypeAux = result;                   
                return boatTypeAux;
            });
        } 

        else {
            return null;
        }       
    };

    var parseDestination = function(url, language) {

        // departure is parsed
        var departure = UrlService.parseUrlDeparture(url);
        return $http.get("http://" + API_SERVER_URL + "/translatedDepartures?departure="+departure+";lang="+ language+";matchStart="+true).then(function(response) {                        
            departure = response.data.map(function(source) { 
                return source.element_translation; 
            });

            ...

注意:当我在parseBoatType函数中运行BoatType.getBoatTypeByName时,代码仍在运行,我在获得结果之前运行searchBoats。

更新

searchBoats方法如下所示:

var searchBoats = function(destination, boatType) { 

    Boat.query({
        destination: destination, 
        boatType: boatType
    }, function success(result) {
        console.log("getOptionList.query realizada");
        $scope.boats = result;           

        ...

根据您的回答,我有回电BoatType.getBoatTypeByName({name: boatTypeParsed}, function success(result) { boatTypeAux = result;致电我的工厂的工厂服务:

angular.factory('BoatType',
    function ($resource, SERVER_URL) {
        var boatTypes =
            $resource('http://' + SERVER_URL + '/:action', {
                action: 'boat_types'
            }, {
                query: {
                    method: 'GET',
                    isArray: true
                },
                getBoatTypeById: {
                    method: 'GET',
                    params: {
                        action: 'getBoatTypeById'
                    },
                    isArray: false
                },
                getBoatTypesById: {
                    method: 'GET',
                    params: {
                        action: 'getBoatTypesById'
                    },
                    isArray: true
                },
                getBoatTypeByName: {
                    method: 'GET',
                    params: {
                        action: 'getBoatTypeByName'
                    },
                    isArray: false
                }
            });
        return boatTypes;
    }
)

新更新 根据@ zero298的评论,现在我的代码如下:

  var parseURL = function() {                           
        var language = $routeParams.language;                           
        var url = $location.path(); 

        // You need to wait on your async calls
        var boatsPromise = $q.all([
            parseBoatType(url, language),
            parseDestination(url, language)
        ]).then(function(resultArr){
            var boatType = resultArr[0],
                destination = resultArr[1];

            // Return something else to wait on
            return searchBoats(destination, boatType);
        });

   var parseBoatType = function(url, language) {

            BoatType.getBoatTypeByName({name: boatTypeParsed}, function success(result) {                   
                return result; 
            });
    };  

    var parseDestination = function(url, language) {            
        return "whatever";              
    };

// The service
.factory('BoatType', 

      function($resource, SERVER_URL){          
        var boatTypes =
         $resource('http://' + SERVER_URL +'/:action', {action:'boat_types'}, {       
            query: {method:'GET', isArray: true},                
            getBoatTypeByName: {method:'GET', params:{action: 'getBoatTypeByName'}, isArray: false}
         });        
         return boatTypes;           
      }
  )

虽然函数searchBoats等到parseBoatType和parseDestination被执行,但是注意parseBoatType有一个对API的资源调用的服务回调(我觉得它是asynchnous),因此,searchBoats函数在执行之前执行回调得到结果。

1 个答案:

答案 0 :(得分:0)

您没有等待任何异步调用。请查看$http和扩展名$q的文档。

你需要做这样的事情:

function parseURL() {
    var language = $routeParams.language;
    var url = $location.path();

    // You aren't waiting on anything that is async

    // You need to wait on your async calls
    var boatsPromise = $q.all([
        parseBoatType(url, language),
        parseDestination(url, language)
    ]).then(function(resultArr){
        var boatType = resultArr[0],
            destination = resultArr[1];

        // Return something else to wait on
        return searchBoats(destination, boatType);
    });

    // Either wait on it here and do some more stuff
    boatsPromise.then(console.log);

    // Or return it so that something higher in the callstack can wait
    return boatsPromise;
}

您的searchBoats函数也应该像parseDestination一样,并返回$q(承诺)等待:

function searchBoats(destination, boatType) {
    /*
     * I would recommend against putting stuff on to $scope
     * in an async chain unless you are at the very root
     * of the chain otherwise you lose context
     * and are unable to .then()
     */

    // Retun a then()able object
    return Boat.query({
            destination: destination,
            boatType: boatType
        },
        function success(result) {
            console.log("getOptionList.query realizada");
            return result;
        });
}