網站搜尋

angular - 連續呼叫 HTTP 請求 100 次


這裡是問題陳述:

  • 兩個服務呼叫(/api/postsomedata)和(/api/postsomeotherdata)
  • 將這兩個服務呼叫依次各呼叫100次(雖然這兩個服務呼叫之間沒有相互依賴)

我想出以下使用嵌套 concatMap 的 rxjs 實作方法:

import { range } from 'rxjs/observable/range';
import { concatMap } from 'rxjs/operators';
import { tap } from 'rxjs/operators/tap';

@Component({
  selector: 'app-flow',
  templateUrl: './flow.component.html',
  styleUrls: ['./flow.component.scss']
})
export class FlowComponent implements OnInit {

  constructor(public dataCallService: DataCallService) { }
  ngOnInit() {
    range(1, 100).pipe(
      tap((d) => console.log(d)),
      concatMap(() => this.dataCallService.firstAPI(data1).pipe(
        concatMap(() => this.dataCallService.secondAPI(data2))
      ))
    ).subscribe(res => {
      console.log(res)
    });
  }
 }

雖然這個方法運作正常;我使用的 tap 運算子會立即發出 1 到 100。我不確定這是不是正確的方法。是否有更好的方法達成相同的效果?

答案#1

為了使請求能夠串接,應該是這樣的:

Observable.range(1, 100).map(i =>
  this.dataCallService.firstAPI(data1)
  .concatMap(() => this.dataCallService.secondAPI(data2))
})
.concatAll()
.subscribe(res => {});

在 Angular 中,請求的可觀察對象可以方便地使用 promises 處理,因為 Http 和 HttpClient 都會產生具有單一值的完整可觀察對象。

除非請求可觀察對象預計會在請求中途被中止,或與其他未完成/多值的可觀察對象串接,否則切換到 Promise 可能會更有利。

這導致非常簡單明瞭的 async 函數,其中 Promise.all 被用於可以平行執行的請求:

  async ngOnInit() {
    try {
      for (let i = 0; i < 100; i++) {
        const [result1, result2] = await Promise.all([
          this.dataCallService.firstAPI(data1).toPromise(),
          this.dataCallService.secondAPI(data2).toPromise()
        ]);
      }
    } catch (err) { ... }
  }

或串聯:

  async ngOnInit() {
    try {
      for (let i = 0; i < 100; i++) {
        const result1 = await this.dataCallService.firstAPI(data1).toPromise();
        const result2 = await this.dataCallService.secondAPI(data2).toPromise();
      }
    } catch (err) { ... }
  }