Angular2 - How to chain async service calls (http requests) in a component?

北战南征 提交于 2019-11-30 08:19:20

问题


I have a component which first need to call a service that POST something. Then in the same component I want to wait until the POST is done, to call another service which GETs data.

How can I make the GET call wait for the POST call to finish?

In new-version.component.ts:

private createNewVersion(value) {
    ...

    // create new version, then call on all available versions

    // POST call
    this._newVersionService.createNewVersion(vnr);

    // GET call
    this._versionService.getAvailableVersions(); 

    ...
}

In new-version.service.ts:

export class NewVersionService {

response$: Subject<any>;

constructor(private _http: Http) {
    this.response$ = new BehaviorSubject<any>(null);
 }

public createNewVersion(versionNr) {    
    this._http.post('http://localhost:8080/services/' + versionNr, null, {
        method: 'POST',
    })
    .subscribe(response => {
        this.response$.next(response.status);
    },
    error => console.error(error));
}

Thanks!


回答1:


When a call returns a Promise chain the calls with

someFunction() {
  return returnsPromise()
    .then(result => doSomethingNext())
    .then(result => doSomethingAfterThat());
}

Ensure you have a return that returns the Promise of that chain so the caller of someFunc() also has a chance to time additional work to execute after doSomethingAfterThat() is completed.

When a call returns an Observable then use the complete callback

someFunction() {
  return returnsObservable()
    .subscribe(
      event => doForEachEvent(),
      error => handleError(),
      () => doSomethingNext()
          .then(result => doSomethingAfterThat());
}

doSomethingNext() is executed after the last event and doSomethingAfterThat() is again chained with then() to show how to mix observable and promise. doSomething().




回答2:


You should be able to concat to achieve sequence, and reduce to collect the emitted values:

var a = this._newVersionService.createNewVersion(vnr);
var b = this._versionService.getAvailableVersions(); 

Rx.Observable.concat(a, b).reduce((acc:Array<any>, x:any) => {
    acc.push(x); return acc;
}, []).subscribe(t=> { 
      var firstEmitted = t[0];
      var secondEmitted = t[1];
});



回答3:


You can do like this: Change createNewVersion to:

public createNewVersion(versionNr) {
 return this._http.post('http://localhost:8080/nod_inspection_plugin/services/' + versionNr, null, {
    method: 'POST',
 });
}

Then in your call:

this._newVersionService.createNewVersion(vnr).subscribe(response=> {
 this._versionService.getAvailableVersions(); 
}, error => console.error(error));



回答4:


Another way to do the same is to subscribe in the new-version.component.ts and call you GET request from within the POST request i.e check whether your POST request is done Correctly or not if yes POST is done Properly then call you GET request. As below:

In new-version.component.ts:

 private createNewVersion(value) {
    ...
    // create new version, then call on all available versions

    // POST call
    this._newVersionService.createNewVersion(vnr)
        .subscribe((res) => {
            if(res){
                console.log(res);
                if (---Post request done properly check via status or something else here----{
                    CALL YOUR GET REQUEST HERE.....
                    // GET call 
                    this._versionService.getAvailableVersions(); 
                }
                else {
                    DO something else whatever you want....
                }
            }
        });
    ...
}

In new-version.service.ts:

export class NewVersionService {

response$: Subject<any>;

constructor(private _http: Http) {
    this.response$ = new BehaviorSubject<any>(null);
 }

public createNewVersion(versionNr) {    
    this._http.post('http://localhost:8080/nod_inspection_plugin/services/' + versionNr, null, {
        method: 'POST',
    })
    .map(response => {
        return [{status: response.status, json: response.json()}];
    },
    error => console.error(error));
}

for more info related to http request you can read here.




回答5:


Better use switchMap() here.

const versions$ = this._newVersionService.createNewVersion(vnr)
                 .switchMap(response => this._versionService.getAvailableVersions());

versions$.subscribe(response2 => this.versions = response2)

But the problem will be if you make another POST request before first has been resolved, the previous request will get cancelled.



来源:https://stackoverflow.com/questions/35173649/angular2-how-to-chain-async-service-calls-http-requests-in-a-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!