Angular2 - 如何在组件中链接异步服务调用(http请求)?

11

我有一个组件,首先需要调用一个POST服务来发送一些内容。然后在同一个组件中,我想等待POST完成后再调用另一个GET服务来获取数据。

我该如何让GET调用等待POST调用完成?

在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(); 

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

谢谢!


我这里有一个链式调用的例子:http://www.syntaxsuccess.com/viewarticle/angular-2.0-and-http。我的示例是一个get请求,但你可以将其改为post请求。 - TGH
5个回答

7
当一个调用返回一个 Promise 链时,使用链式调用。
someFunction() {
  return returnsPromise()
    .then(result => doSomethingNext())
    .then(result => doSomethingAfterThat());
}

确保你有一个返回该链的Promise的return,这样someFunc()的调用者在doSomethingAfterThat()完成后也有机会定时执行其他工作。

当调用返回Observable时,请使用complete回调函数。

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

doSomethingNext()会在最后一个event之后执行,doSomethingAfterThat()再次与then()链接以展示如何混合使用Observable和Promise。doSomething()


1
你应该能够使用concat来实现序列,使用reduce来收集发出的值:
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];
});

0
你可以这样做: 将 createNewVersion 改为:
public createNewVersion(versionNr) {
 return this._http.post('http://localhost:8080/nod_inspection_plugin/services/' + versionNr, null, {
    method: 'POST',
 });
}

然后在你的调用中:

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

0

另一种实现相同功能的方法是在 new-version.component.ts 中进行 subscribe,并从 POST 请求中调用你的 GET 请求,即检查你的 POST 请求是否正确完成, 如果是,则正确执行 POST 请求,然后调用你的 GET 请求。如下所示:

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

如果您想了解更多关于http请求的信息,可以在这里阅读


你曾经读过你自己的代码吗?你的代码很难读。可能这就是原因。 - Playdome.io

0
最好在这里使用switchMap()
const versions$ = this._newVersionService.createNewVersion(vnr)
                 .switchMap(response => this._versionService.getAvailableVersions());

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

但是问题在于,如果在第一个POST请求解决之前发起另一个请求,那么先前的请求将被取消。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接