2017-11-13 9 views
1

그래서 for 루프를 사용하여 빠르게 연속적으로 패키지를 만들려고합니다. 나는 이것을 for 루프와 api 호출로하려고하는데,이 api 호출은 패키지를 만든다. 내 루프는 각 통화가 반환 될 때까지 기다려야하지만 그렇지 않습니다.각도 4의 http.post를 사용하여 api에서 응답을 기다리십시오.

또한 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

나는 그것을 위해 재귀 함수를 만들 것입니다 :

0

루프를 관찰 가능하게 만들고 패키지를 만들려면 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()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>

에게있어