Search code examples
observablengrx

NGRX: subscribe to Observable return by select method is sync or async?


I'm using NGRX in my Angular project, as we know the return value of store.select is type of Observable. And in one of my service, I plan to get the state value, and use this value as input parameter of API request. As following:

// the userIDs$ is return by store.select method
this.demoService.userIDs$.subscribe((res) => {
  console.log('userids', res); //  output first
})
console.log('after wellids...') //  output after the console in subscription callback
this.http.post<string[]>(
  url, 
  { ids: userids} // the user ids as input parameter
);

My question is subscribe to the userIDs observable, the callback is sync or async? Based on my debugging, the first console run before the second one(the one outside the subscription). Thank you


Solution

  • Within NGRX, the store itself is just a BehaviorSubject.

    When a new value is being emitted into a BehaviorSubjet, all the callbacks will be called on the same tick so it's basically synchronous. Of course, if you applied before the callback a delay for ex, it'd then become asynchronous.

    That said, I wouldn't encourage you to use the store this way and I'd just re-write your code as the following:

    this.demoService.userIDs$.pipe(
      first(),
      tap(userIDs => console.log({ userIDs })),
      mergeMap(userIDs => this.http.post<string[]>(url, { ids: userids }))
    );
    

    This way you do not care at all whether it's synchronous or asynchronous. You just keep the whole data source into one stream.

    It's also safer because if when calling that stream later in your app, you'll have the ability to cancel it (with a switchMap).

    Also, note the use of first because in your case your keeping the userIDs$ stream opened (which I believe in that case would be a memory leak).