0

在我的 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但我真的不知道如何使用它们。有什么办法可以编写上面的代码,更好,更安全?

在此先感谢您的帮助!

4

2 回答 2

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);
          });
于 2014-07-07T14:45:26.160 回答
1

如果您需要一个接一个地执行承诺,您将使用像 Maxim 提到的链。多一题:

如果您需要执行更多的承诺然后解决它,您将使用“$q.all”。

见文档:

更新

不确定我是否理解得很好,但您应该使用 q.all 和链接的组合。再次,对不起,如果我没有很好地理解你。

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. 
于 2014-07-07T15:10:07.583 回答