2017-11-13 12 views
1

私はforループを使ってパッケージをすばやく連続して作成しようとしています。私はforループとapi呼び出しでこれを実行しようとしますが、このapi呼び出しはパッケージを作成します。私のループは、各呼び出しの戻りを待たなければならないが、それはしない。http.postを使ってapiからの応答を待つ4

また、私はbackend.serviceをObservableの代わりにPromiseに変更したくありません。 Observableでこれを行うことは可能ですか?

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!"; 
    }); 
} 

をして起動します。

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); 
} 

答えて

0

私はそれのために再帰関数を作成したいです: this.createPackages(this.dataArray.length);

0

ループを観測可能にして、concatMap()というパッケージを作成することができます。

遅い場合はコールバックが問題になることがあります。あなたは外部の購読のそれらを実行したいかもしれません。 flatMap()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!"; 
    } 
    ) 

は、ここでいくつかのダミーコード

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>

です
関連する問題