Возврат внутреннего обещания $ http - PullRequest
2 голосов
/ 04 июня 2019

У меня есть две услуги:

ProductService

CartService

и контроллер:

ShoppingController

ShoppingController необходимо загрузить корзину с сервера. Чтобы CartService мог это сделать, ProductService должен сначала загрузить продукты.

ProductService.js

ProductService.DownloadProducts = function(){
          if(alreadyHaveDownloadedProducts){                   
              return {
                  success: function (fn) {
                      fn(products);
                  }
              };
          }else{
              if(getProductsPromise== null){
                  getProductsPromise= $http.post("Api/GetProducts")  
              }
              return getProductsPromise;
          }

CartService.js

CartService.DownloadCart = function(){
    ProductService.DownloadProducts().success(function(){
          if(alreadyHaveDownloadedCart){   
              //Dont need to go to server                
              return {
                  success: function (fn) {
                      fn(cart);
                  }
              };
          }else{
              if(getCartPromise == null){
                  getCartPromise = $http.post("Api/GetCart")  
              }
              return getCartPromise; //<= The promise I actually want to return
          }
    })
}

ProductService.DownloadProducts

ShoppingController.js

CartService.DownloadCart().success(function(){DisplayCart()});

Пока что этот подход хорошо работает, потому что, если ProductService уже был вызван на другой странице, мне не нужно возвращаться на сервер. То же самое для службы корзины. Проблема в том, что в настоящее время я не могу вернуть getCartPromise, поскольку он не был создан до тех пор, пока асинхронный продукт GetProducts не вернул

Можно ли структурировать это так, чтобы я мог вернуть внутреннее обещание ShoppingController, сохраняя при этом хороший синтаксис .success ()?

1 Ответ

0 голосов
/ 04 июня 2019

Мой способ похож на ваш, но вместо сохранения некоторого alreadyHaveDownloadedCart (логического флага) я кеширую обещание само по себе, а затем возвращаю его.

Я кеширую обещание для данных класса обслуживания, а затем возвращаю его, если оно существует, в противном случае инициализирую вызов сервера.

Нечто подобное:

class ProductService {
  constructor() {
    this.productsPromise = null;
  }

  DownloadProducts() {
    if(!this.productsPromise) {
      this.productsPromise = $http.post('Api/GetProducts');

      this.productsPromise.then(products => this.products = products);
    }

    return this.productsPromise.then(() => this.products);
  }
}

class CartService {
  constructor(ProductService) {
    this.ProductService = ProductService;
    this.cartPromise = null;
  }

  DownloadCart() {
    return this.ProductService.DownloadProducts().success(() => {
      if (!this.cartPromise) {
        this.cartPromise = $http.post('Api/GetCart');
        this.cartPromise.then((cart) => {
          this.cart = cart;
        });
      }

      return this.cartPromise.then(() => this.cart);
    });
  }
}

...