角度构造来自不同承诺的ViewModel

时间:2014-07-07 14:37:27

标签: javascript angularjs q angular-ui-router angular-promise

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

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

  

它有效但我的问题是我能不能写得更好。

是。您可以编写保证链。优点是:错误传播,你可以在链的末端捕获它,而不是像Javascript中的异步调用那样piramide

参见下面的流程示例:

enter image description here

<强> [编辑]

如果订单不重要,您可以使用$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.