簡體   English   中英

如何在 observable (rxjs) 中等待 http 響應

[英]how to wait http response in observable (rxjs)

這是原始代碼。

// info.service.ts.  

  this.info$ = new BehaviorSubject<Info>(null);

  async getInfo() {
    try {
      const info = await this.infoApi.getInfo();
      console.log(info) // info {name: 'sdf', 'age': 12}
      this.info$.next(info);
    } catch {
      this.info$.next(null);
    }
  }



  // infoApi Class
  getInfo() {
    return this.apiService.get<Info>(`/info`, this.infoService....);
  }

對於使用 rxjs 進行異步處理,我們修改代碼如下。 我項目中的其他異步處理代碼也通過如下方式修改為rxjs,運行正常。 但是,只有 getinfo 服務不能正常工作。 異步處理未正常進行。 作為檢查網絡面板的結果,信息數據請求在管理狀態下被檢查。 如果有任何預期的問題,請告訴我。
(異步,等待不可用,所以我正在嘗試使用 Rxjs。)

兩個版本的代碼都沒有按預期工作。

第一個版本

// info.service.ts
  getInfo() {
    from(this.infoApi.getInfo()).subscribe(
      info => {this.info$.next(info); 
      console.log(info) // null
      error => {this.info$.next(error)
      }
    )
  }

  // infoApi Class
  getInfo() {
    return this.apiService.get<Info>(`/info`, this.infoService....);
  }

// api.service.ts
  get<T>(url: string, opts?: options) {
    return this.request<T>('GET', url, null, opts);
  }

第二版

// info.service.ts
  getInfo() {
   this.infoApi.getInfo().subscribe(
      info => {this.info$.next(info); 
      console.log(info) // null
      error => {this.info$.next(error)
      }
    )
  }

  // infoApi Class
  getInfo() {
    return from(this.apiService.get<Info>(`/info`, this.infoService....);
  }

// api.service.ts
  get<T>(url: string, opts?: options) {
    return this.request<T>('GET', url, null, opts);
  }

getInfo() 返回一個 Observable,不需要在 info.servive.ts 中使用 from()。

訂閱部分中的格式也可以是:

  getInfo() {
    this.infoApi.getInfo()
    .subscribe({
      next: (info => {this.info$.next(info); 
      console.log(info)}), // null
      error: (error => this.info$.next(error))
      }
    )
  }

我使用 randomAPI 構建了一個小例子

信息服務.ts

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

// Using random data api for example
export type Info = {
  blend_name: string;
};

@Injectable({
  providedIn: 'root',
})
export class infoApiService {
  info$: BehaviorSubject<Info> = new BehaviorSubject<Info>(null);

  constructor(private http: HttpClient) {
    // Use subscription for making BehaviorSubject work...
    this.getInfo().subscribe()
  }

  getInfo() {
    return this.http
      .get<Info>('https://random-data-api.com/api/coffee/random_coffee')
      .pipe(
        tap({
          next: (info) => {
            this.info$.next(info);
            console.log('logging in tap', info);
          },
          error: (error) => this.info$.error(error),
        })
      );
  }
}

app.component.ts

import { Component, OnInit, VERSION } from '@angular/core';
import { Observable } from 'rxjs';
import { Info, infoApiService } from './info.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {

  infoObs$!: Observable<Info>;

  constructor(private info: infoApiService) {
    this.infoObs$ = this.info.info$.asObservable();
  }
}

app.component.html

<div *ngIf="infoObs$ | async">
  <h3>The info is here : {{ (infoObs$ | async).blend_name }}</h3>
</div>

它在 StackBlitz 中可用: https ://stackblitz.com/edit/angular-ivy-wgjsfa?file=src%2Fapp%2Fapp.component.html,src%2Fapp%2Fapp.component.ts,src%2Fapp%2Finfo.service .ts

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM