Angular:承诺依赖于路由中的其他承诺

时间:2015-03-22 16:55:52

标签: javascript angularjs promise angular-promise angular-routing

当谈到Angular(或一般)中的承诺时,我有点困惑,我只是不能按照我想要的方式使用它。

我无法分享我正在使用的代码,但这里有一些模型代码:

var personModule = angular.module('personModule', [], ['$routeProvider', function($routeProvider){
    $routeProvider
    .when('/person/:personId/cars',{
        templateUrl: 'partials/personCars.html',
        controller: 'personCarsController',
        resolve: {
            'person': resolvePerson,
            'cars': resolveCars
        }
    });
}]);

function resolvePerson($route, personFactory){
    var personId = $route.current.params.personId;

    return personFactory.getPerson(personId).then(function(response){
        return angular.fromJson(response).data;
    });
}

function resolveCars($route, personFactory, carFactory){
    var personId = $route.current.params.personId;

    return personFactory.getPersonCars(personId).then(function(response){
        var cars = angular.fromJson(response).data;

        angular.forEach(cars, function(car){
            carFactory.getModel(car.modelId).then(function(response){
                car.model = angular.fromJson(response).data;

                carFactory.getMaker(car.model.makerId).then(function(response){
                    car.model.maker = angular.fromJson(response).data;
                });
            });
        });

        return cars;
    });
}

汽车的数据格式在JSON中将是这样的:

[
    {
        "year": "1992",
        "color": "red",
        "modelId": 1,
        "model": 
        {
            "name": "Corolla",
            "makerId": 1,
            "maker":
            {
                "name": "Toyota"
            }
        }
    },
    {
        "year": "1998",
        "color": "black",
        "modelId": 1,
        "model": 
        {
            "name": "Escort",
            "makerId": 2,
            "maker":
            {
                "name": "Ford"
            }
        }
    }
]

现在上面的代码工作得很好。只是当我点击链接打开页面时,数据随着承诺的解决而延迟。路线等待人和车解决,但不是每辆车的型号和制造商,这是我想要发生的。我已经在所有关于承诺和延期的Angulars文件中漫步,我现在正处于亏损状态。

修改

function resolveCars($route, personFactory, carFactory){
    var personId = $route.current.params.personId;
    var promises = [];

    return personFactory.getPersonCars(personId).then(function(response){
        var cars = angular.fromJson(response).data;

        angular.forEach(cars, function(car){
            promises.push(carFactory.getModel(car.modelId).then(function(response){
                console.log("Resolving model");
                car.model = angular.fromJson(response).data;

                promises.push(carFactory.getMaker(car.model.makerId).then(function(response){
                    console.log("Resolving maker");
                    car.model.maker = angular.fromJson(response).data;
                }));
            }));
        });

        return $q.all(promises).then(function(){
            console.log("Resolved");
            return cars;
        });
    });
}

按建议更改了代码,现在它等待carModel解析但不是carMaker。

一辆车的控制台输出是:

Resolving model
Resolved
Resolving maker

编辑2:

解决了它:)改变了

promises.push(carFactory.getMaker(car.model.makerId).then(function(response){
    console.log("Resolving maker");
    car.model.maker = angular.fromJson(response).data;
}));

部分到

return carFactory.getMaker(car.model.makerId).then(function(response){
    console.log("Resolving maker");
    car.model.maker = angular.fromJson(response).data;
});

感谢您的帮助!我知道我的原始代码不会像我想要的那样工作,但是对于我的生活无法理解我应该如何改变它。

1 个答案:

答案 0 :(得分:1)

这种情况发生了,因为只要解决了承诺,您就会在路径的'resolve'属性中定义路由。

在您的resolveCars功能中,您可以解析汽车,然后在里面启动后台“resolveModels”功能。尽管如此,“汽车”已经解决,你确实将其归还。后台任务不会阻止解除承诺。

当所有汽车的车型都得到解决时,您可以返回另一个只会解决的承诺。

你可以这样做:

function resolveCars($route, personFactory, carFactory, $q) {
    var personId = $route.current.params.personId;

    return personFactory.getPersonCars(personId).then(function (response) {
        var cars = angular.fromJson(response).data;
        var promises = [];
        var deferred = $q.defer();


        angular.forEach(cars, function (car) {
            var modelWithMakerPromise = carFactory.getModel(car.modelId).then(function (response) {
                car.model = angular.fromJson(response).data;
                return car.model;
            }).then(function (model) {
                return carFactory.getMaker(model.makerId).then(function (response) {
                    model.maker = angular.fromJson(response).data;
                });
            });
            promises.push(modelWithMakerPromise);
        };
        $q.all(promises).then(function () {
            defered.resolve(cars);
        });
        return defered.promise;
    });

这未经过测试,但应该有效并给你一个想法。 基本上我创造了一个新的承诺,我回来了。只有当所有carModel Promise解决时,这个承诺才会解决。 看看$q Api Doc

问候