调用Sequencial HTTP请求100次

时间:2018-04-14 07:43:09

标签: angular typescript rxjs

这是问题陈述:

  • 两次服务电话(/api/postsomedata)和(/api/postsomeotherdata
  • 按顺序调用两次服务调用(虽然这两个服务调用之间没有相互依赖)

我想出了使用嵌套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 个答案:

答案 0 :(得分:2)

为了将请求链接起来,它应该是:

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

可以使用Angular中的promise来方便地处理请求observable,因为HttpHttpClient都会导致单个值的完全可观察。

除非请求observable应该在请求中间中止或者使用其他不完整/多值可观察对象进行管道传递,否则切换到promises可能是有益的。

这导致非常简单的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) { ... }
  }