Angular: Promise依赖于路由中的其他promise
Angular: Promise dependant on other promises in routing
当谈到 Angular 中的 promise(或一般而言)时,我有点困惑,我无法让这个按照我想要的方式工作。
我无法分享我正在使用的代码,但这里有一些模型代码:
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"
}
}
}
]
现在上面的代码可以正常工作了。只是当我单击 link 打开页面时,随着承诺的解决,数据会出现延迟。路由等待人和汽车来解决,而不是等待每辆车的型号和制造商,这是我希望发生的事情。我浏览了所有 Angular 关于 promises 和 defer 的文档,但我现在不知所措。
编辑:
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;
});
感谢您的帮助!我知道我的原始代码不会像我想要的那样工作,但我终究无法弄清楚我应该如何更改它。
发生这种情况是因为路由已解析,一旦承诺已解析,您在路由的 'resolve' 属性 中定义。
在您的 resolveCars 函数中,您解析汽车,然后在内部启动您的后台 "resolveModels" 函数。尽管如此,'cars' 已解决,您可以 return 解决。后台任务不会阻止承诺的解决。
你可以return另一个承诺,只有当所有汽车的型号都被解析时才会解析。
你可以这样做:
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;
});
这还没有经过测试,但应该可以工作并给你一个想法。
基本上我创建了一个新的承诺,我 return。只有当所有这些 carModel Promise 都 resolve 时,这个 promise 才会 resolve。
看看$q Api Doc
问候
当谈到 Angular 中的 promise(或一般而言)时,我有点困惑,我无法让这个按照我想要的方式工作。
我无法分享我正在使用的代码,但这里有一些模型代码:
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"
}
}
}
]
现在上面的代码可以正常工作了。只是当我单击 link 打开页面时,随着承诺的解决,数据会出现延迟。路由等待人和汽车来解决,而不是等待每辆车的型号和制造商,这是我希望发生的事情。我浏览了所有 Angular 关于 promises 和 defer 的文档,但我现在不知所措。
编辑:
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;
});
感谢您的帮助!我知道我的原始代码不会像我想要的那样工作,但我终究无法弄清楚我应该如何更改它。
发生这种情况是因为路由已解析,一旦承诺已解析,您在路由的 'resolve' 属性 中定义。
在您的 resolveCars 函数中,您解析汽车,然后在内部启动您的后台 "resolveModels" 函数。尽管如此,'cars' 已解决,您可以 return 解决。后台任务不会阻止承诺的解决。
你可以return另一个承诺,只有当所有汽车的型号都被解析时才会解析。
你可以这样做:
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;
});
这还没有经过测试,但应该可以工作并给你一个想法。 基本上我创建了一个新的承诺,我 return。只有当所有这些 carModel Promise 都 resolve 时,这个 promise 才会 resolve。 看看$q Api Doc
问候