admin管理员组

文章数量:1336660

I have a login process that has fairly plicated login variations and has to be scalable to easily add more in the future. So initially the user is authenticated in the typical manner and a user object is returned. Then I must make additional http calls to get information that will determine the various requirements before the user is granted access to the app. This is done using some of the values returned in the user object. I want to write the code in a way that I can easily add http calls without changing current code so I thought using fork join for the subsequent calls would be good since they can be done in parallel. Below is my working code.

I can easily add new requests to the fork join call and while it doesn't look too bad to me I have been told nested subscriptions is a code smell and typically bad practice. Any ideas on how to do this better would be great.

Thanks.

this.authenticate.login(this.model)
  .subscribe(
    _data => {
      this.subscription = Observable.forkJoin(
        this.devicesHttp.getDevicesByMacAddress(this.macAddress),
        this.teamsService.getTeamsByUserId(_data['userId'])
      );

      this.subscription.subscribe(
        _data => {
          // Check login type and other stuff...
        }
      );
    }
  );

I have a login process that has fairly plicated login variations and has to be scalable to easily add more in the future. So initially the user is authenticated in the typical manner and a user object is returned. Then I must make additional http calls to get information that will determine the various requirements before the user is granted access to the app. This is done using some of the values returned in the user object. I want to write the code in a way that I can easily add http calls without changing current code so I thought using fork join for the subsequent calls would be good since they can be done in parallel. Below is my working code.

I can easily add new requests to the fork join call and while it doesn't look too bad to me I have been told nested subscriptions is a code smell and typically bad practice. Any ideas on how to do this better would be great.

Thanks.

this.authenticate.login(this.model)
  .subscribe(
    _data => {
      this.subscription = Observable.forkJoin(
        this.devicesHttp.getDevicesByMacAddress(this.macAddress),
        this.teamsService.getTeamsByUserId(_data['userId'])
      );

      this.subscription.subscribe(
        _data => {
          // Check login type and other stuff...
        }
      );
    }
  );
Share Improve this question edited Jun 1, 2017 at 14:16 Aaron Balthaser asked Jun 1, 2017 at 14:02 Aaron BalthaserAaron Balthaser 2,6443 gold badges39 silver badges62 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

For example like this using the concatMap() operator:

this.authenticate.login(this.model)
    .concatMap(_data => Observable.forkJoin(
        this.devicesHttp.getDevicesByMacAddress(this.macAddress),
        this.teamsService.getTeamsByUserId(_data['userId'])
    ))
    .subscribe(_data => {
          // Check login type and other stuff...
    });

The Observables in forkJoin will run in parallel and forkJoin will wait until they both finish.

Also concatMap() waits until the inner Observable pletes and then pushes the result further.

In 2021 this must be written with pipe, stand-alone operators, array in forkJoin and Observer argument in subscribe:

import { concatMap, forkJoin } from 'rxjs';

this.getFirst().pipe(
  concatMap(data =>
    forkJoin([
      this.getSecond(data),
      this.getThird(data)
    ])
  )
).subscribe({
  next: result => ...,
  error: e => ...
});

How about this:

this.authenticate.login(this.model)
  .switchMap(data => Observable.forkJoin(
    this.devicesHttp.getDevicesByMacAddress(this.macAddress),
    this.teamsService.getTeamsByUserId(data['userId'])
  ))
  .subscribe(...,...)

本文标签: javascriptBetter way to use fork join subsequent to another observableStack Overflow