繁体   English   中英

在Angular 4中使用http.post等待来自api的响应

[英]Wait for response from api using http.post in Angular 4

因此,我尝试使用for循环快速连续地创建软件包。 我尝试通过for循环和api调用来完成此操作,此api调用使程序包生效。 我的循环必须等待每次调用返回,但并非如此。

我也不想将backend.service更改为Promise而不是Observable。 是否可以通过Observable做到这一点?

component.ts

for (let i = 0; i < this.dataArray.length; i++) {
  this.backend.createPackage(this.package, this.hasPackagePhoto, this.wantsPackageLabel).subscribe(data => {
    let d = data as any;
    this.backend.packageTrackTrace = d.package.tracktrace;
    this.backend.awsLink = d.label;
  }, error => {
    this.backend.showMessage(false, 'Foutcode 2a: Het toevoegen van een pakket is niet gelukt.');
    console.log(error);
    this.errorMsg = "Verkeerde postcode!";
  }
  );
}

backend.service.ts

createPackage(p: Package, photo: Boolean, label: Boolean): Observable<Response> {
    const h = new Headers({ 'Content-Type': 'application/json', 'x-access-token': this.auth.getToken() });
    const options = new RequestOptions({ headers: h });

    const pt: any = {
        type: p.type,
        sender: p.sender,
        recipient: p.recipient,
        weight: p.weight,
        value: p.value,
        photo: photo,
        label: label,
        instructions: p.instructions
    };
    if (p.owner != null) {
        pt.owner = p.owner;
    }
    if (p.size != null) {
        pt.size = p.size;
    }

    return this.http.post(`${this.config.apiBase}/packages`, pt, options)
        .map((res:Response) => {
            this.newPackageCallbacks.forEach(cb => {
                cb();
            });
            return this.parseJSON(res);
        })
        .catch(this.handleError);
}

我将为其创建一个递归函数:

createPackages(count: number, i = 0) {
  if (i >= count) return;
  this.backend.createPackage(this.package, this.hasPackagePhoto, this.wantsPackageLabel).subscribe(data => {
    let d = data as any;
    this.backend.packageTrackTrace = d.package.tracktrace;
    this.backend.awsLink = d.label;
    this.createPackages(count, ++i);
  }, error => {
    this.backend.showMessage(false, 'Foutcode 2a: Het toevoegen van een pakket is niet gelukt.');
    console.log(error);
    this.errorMsg = "Verkeerde postcode!";
  });
}

并调用: this.createPackages(this.dataArray.length);

您可以将循环设置为可观察和concatMap()concatMap()

如果回调很慢,则可能是个问题。 您可能要执行外部订阅中的那些。

Observable.from(this.dataArray)
  .concatMap(() => 
    this.backend.createPackage(this.package, this.hasPackagePhoto, this.wantsPackageLabel);
  )
  .subscribe(
    data => {

      // Execute callbacks here if they need to complete before next package 
      this.backend.newPackageCallbacks.forEach(cb => {
        cb();
      });

      let d = data as any;
      this.backend.packageTrackTrace = d.package.tracktrace;
      this.backend.awsLink = d.label;
    }, 
    error => {
      this.backend.showMessage(false, 'Foutcode 2a: Het toevoegen van een pakket is niet gelukt.');
      console.log(error);
      this.errorMsg = "Verkeerde postcode!";
    }
   )

为了说明concatMap() vs flatMap() ,下面是一些虚拟代码

 console.clear() const Observable = Rx.Observable; // Dummy setup for testing let counter = 0; const backendService = { createThePackage: () => { return Observable.of('y' + counter++) .delay((6 - counter) * 10) // delay to resolve in order of 3, 2, 1 } } const dataArray = [1,2,3] // flatMap takes order of resolving counter = 0; Observable.from(dataArray) .flatMap(() => { return backendService.createThePackage(); }) .subscribe(x => { console.log('flatMap: ' + x) }) // concatMap takes order of creating counter = 0; Observable.from(dataArray) .concatMap(() => { return backendService.createThePackage(); }) .subscribe(x => { console.log('concatMap: ' + x) }) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.js"></script> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM