如何使用htttpclient执行同步操作

时间:2019-02-22 10:06:50

标签: angular httpclient

我遇到了需要调用多个HTTP请求但无法同步的情况。

下面是相同的代码。我无法从HTTP服务设置cartId(在下面注释),但是我可以从服务(在下面注释)

获取响应。
export class ShoppingCartService {

    constructor(private http:HttpClient) { }

    private create() {

        return this.http.post('http://localhost:8090/shoppingcart',{});
    }

    private  getCart(cartId:string):Observable <any>{

        return this.http.get(`http://localhost:8090/shoppingcart/${cartId}`)
        .pipe(map((response)=>{
            return response;
        }));
    }

    private getOrCreateCartId() {
        let cartId = localStorage.getItem('cartId');
        let id;
        if (!cartId) {
            this.create().toPromise().then(result => {
                localStorage.setItem('cartId', result.body.id);
                id = result.body.id;
            });
            return this.getCart(id);
        } else 
        return this.getCart(cartId);
    }

    addToCart(product: Product) {
        let cartId; 
        this.getOrCreateCartId().toPromise().then(response => {
            console.log(response.body.id); //here i am able to print the response
            cartId =  response.body.id;  
        });
        console.log(cartId); //here i am getting the cartId value as the 
        undefined..
    }
}

请帮助我进行同步,我已经尝试了许多解决方案,但是没有任何效果。

2 个答案:

答案 0 :(得分:0)

export class ShoppingCartService {

    constructor(private http:HttpClient) { }

    private create() {

        return this.http.post('http://localhost:8090/shoppingcart',{});
    }

    private  getCart(cartId:string):Observable <any>{

        return this.http.get(`http://localhost:8090/shoppingcart/${cartId}`)
        .pipe(map((response)=>{
            return response;
        }));
    }

    private async getOrCreateCartId() {
        let cartId = localStorage.getItem('cartId');
        let id;
        if (!cartId) {
            let result = await this.create().toPromise();
            localStorage.setItem('cartId', result.body.id);
            return result.body.id;

        } else 
          return cartId;
    }

    addToCart(product: Product) {
        let cartId; 
        this.getOrCreateCartId().then((id) => {
           // HERE you get your cartId
           console.log("CartId", id);
           this.getCart(id).toPromise().then(response => {
                ... 
                // HERE you get your cart items
           });
        });
        this.getOrCreateCartId().toPromise().then(response => {

        });
        console.log(cartId); //here i am getting the cartId value as the 
        undefined..
    }
}

答案 1 :(得分:0)

由于httpClient是异步方法,因此它等待响应直到到达,然后同步运行内部代码。但是http.get(或post)之后的代码可以同步运行。因此,即使响应尚未到达,也会导致http方法运行后的代码运行,从而导致未定义属性cartId(在代码中)。

为了使事物保持同步,可以将它们放在.subscribe()中,如下所示:

  private getOrCreateCartId() {
    let cartId = localStorage.getItem('cartId');
    let id;
    if (!cartId) {
        this.create().toPromise().then(result => {
            localStorage.setItem('cartId', result.body.id);
            id = result.body.id;
            **return this.getCart(id);**
        });

    } else 
        return this.getCart(cartId);
  }

  addToCart(product: Product) {
    let cartId; 
    this.getOrCreateCartId().toPromise().then(response => {
      console.log(response.body.id); //here i am able to print the response
      cartId =  response.body.id;  
      **console.log(cartId);**
     });
  }
  

其他信息:Promise也以相同的方式工作,即。它也可以使用asnyc方式。

谢谢,希望对您有帮助