【问题标题】:Angular2 - How to chain async service calls (http requests) in a component?Angular2 - 如何在组件中链接异步服务调用(http请求)?
【发布时间】:2016-05-12 10:46:58
【问题描述】:

我有一个组件,它首先需要调用一个发布内容的服务。然后在同一个组件中,我想等到 POST 完成后,再调用另一个获取数据的服务。

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

在新版本.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(); 

    ...
}

在新版本.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 asynchronous angular chaining


【解决方案1】:

当调用返回 Promise 时,使用

链接调用
someFunction() {
  return returnsPromise()
    .then(result => doSomethingNext())
    .then(result => doSomethingAfterThat());
}

确保您有一个return,它返回该链的Promise,这样someFunc() 的调用者也有机会在doSomethingAfterThat() 完成后安排额外的工作来执行。

当调用返回 Observable 时,使用 complete 回调

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

doSomethingNext() 在最后一个 event 之后执行,doSomethingAfterThat() 再次与 then() 链接以显示如何混合 observable 和 promise。 doSomething().

【讨论】:

    【解决方案2】:

    您应该可以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];
    });
    

    【讨论】:

      【解决方案3】:

      你可以这样做: 将 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));
      

      【讨论】:

        【解决方案4】:

        另一种方法是在new-version.component.tssubscribe 并在POST 请求中调用GET 请求,即检查您的POST 请求是否正确完成 如果是,POST 已正确完成,然后打电话给你GET 请求。如下:

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

        在新版本.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请求的更多信息,您可以read here

        【讨论】:

        • 你读过自己的代码吗?您的代码不可读。大概就是这个原因
        【解决方案5】:

        最好在这里使用switchMap()

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

        但问题是,如果您在第一次解决之前发出另一个 POST 请求,之前的请求将被取消。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-03-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-27
          • 2016-06-11
          • 2016-06-10
          • 1970-01-01
          相关资源
          最近更新 更多