在我的Angular项目中,我有一个Promise,它返回一系列产品:
{"Products":[{"Code":123},{"Code":456}]}
然后,对于每个产品代码,我必须分别调用另外两个返回价格和数量的承诺。
我使用ui-router,我目前的实现代码如下:
$stateProvider.state('root.products', {
abstract: true,
url: '/products',
template: '<div data-ui-view=""></div>',
resolve: {
products: ['ProductsService', function (ProductsService) {
return ProductsService.getProducts()
.then(function (response){
var data = response.data;
return data.Products.map(function (product) {
var viewModelProduct = {};
angular.copy(product, viewModelProduct);
//get Price for Each Product
ProductsService.getPrice(product.Code)
.then(function (response) {
viewModelProduct.Price = response.data.Info.Price;
})
//get Quantity for Each Product
ProductsService.getQuantity(product.Code)
.then(function (response) {
viewModelProduct.Quantity = response.data.Info.Quantity;
})
return viewModelProduct;
});
});
}]
}
})
它有效但我的问题是我能不能写得更好。我读到了$q
和$q.all
的用法,但我真的不知道如何使用它们。
有什么方法可以编写上面的代码,更好更安全吗?
提前感谢您的帮助!
答案 0 :(得分:1)
它有效但我的问题是我能不能写得更好。
是。您可以编写保证链。优点是:错误传播,你可以在链的末端捕获它,而不是像Javascript中的异步调用那样piramide
参见下面的流程示例:
<强> [编辑] 强>
如果订单不重要,您可以使用$q.all
获取承诺列表,并在所有承诺成功解决后通知您。
应该是这样的:
$q.all([
ProductsService.getPrice(product.Code),
ProductsService.getQuantity(product.Code)
])
.then(function(result){
viewModelProduct.Price = result[0].data.Info.Price;
iewModelProduct.Quantity = result[1].data.Info.Quantity;
}, function(error) {
alert(error.message);
});
甚至:
var promises = [];
promises.push(ProductsService.getPrice(product.Code));
promises.push(ProductsService.getQuantity(product.Code));
$q.all(promises).then(function(result){
viewModelProduct.Price = result[0].data.Info.Price;
iewModelProduct.Quantity = result[1].data.Info.Quantity;
}, function(error) {
alert(error.message);
});
答案 1 :(得分:1)
如果你需要一个接一个地执行promises,你将使用Maxim提到的链。 更多一个主题:
如果您需要执行更多承诺然后解决它,您将使用&#34; $ q.all&#34;。
见文件:
更新
不确定我是否理解,但你应该使用q.all和chaining的组合。 再一次,对不起,如果我没有理解你。
var p1 = ProductsService.getPrice(product.Code)
.then(function (response) {
return response.data.Info.Price;
});
var p2 = ProductsService.getQuantity(product.Code)
.then(function (response) {
return response.data.Info.Quantity;
});
return $q.all([p1,p2]); // next "then" will get array with price and quantity respectively.