Почему BehaviorSubject не asyn c? - PullRequest
0 голосов
/ 29 мая 2020

Я создал метод, позволяющий возвращать данные, если данные уже были введены в хранилище и загружены, но в этом случае это не async.

Он выглядит только async, если я вставляю переменная снаружи, внутри subscribe.

Что происходит, так это то, что значение равно «true», которое является начальным значением Behavior

SERVICE

export class StoreService {
    constructor(protected readonly userStore: UserStoreService, protected readonly chatStore: ChatStoreService) {}

    create(): void {
        this.userStore.setAll();
        this.chatStore.setAll();
    }

    get loading(): BehaviorSubject<boolean> {
        const isLoading = new BehaviorSubject(true);

        timer(1000).subscribe(() => {
            combineLatest([this.userStore.loading, this.chatStore.loading])
                .pipe(
                    filter(([userLoading, chatLoading]) => !userLoading && !chatLoading),
                    takeWhile(([userLoading, chatLoading]) => !userLoading && !chatLoading)
                )
                .subscribe(() => isLoading.next(false));
        });

        return isLoading;
    }
}

КОМПОНЕНТ:

export class AppComponent implements OnInit {
    constructor(public readonly store: StoreService) {}

    ngOnInit(): void {
        this.store.create();
    }
}

{{ store.loading | async | json }}

Ответы [ 2 ]

0 голосов
/ 01 июня 2020

Проблема get loading() заключается в том, что каждый раз, когда он вызывается, он возвращает новый поток, несмотря на то, что он полагается на this.userStore.loading и this.chatStore.loading.

вам нужно исправить это, как вариант, сделайте это свойство только для чтения, которое делает то же самое:

export class StoreService {
  constructor(protected readonly userStore: UserStoreService, protected readonly chatStore: ChatStoreService) {}

  create(): void {
    this.userStore.setAll();
    this.chatStore.setAll();
  }

  // to add $ to mark it as an observable is a nice style.
  public readonly loading$: Observable<boolean> = combineLatest([
    this.userStore.loading,
    this.chatStore.loading,
  ]).pipe(
    // maps to true if anyone is loading.
    map(flags => flags.indexOf(true) !== -1),

    // our start value is true.
    startWith(true),
  );
}

, и теперь каждый раз, когда один из них или оба загружаются, оно возвращает true, в противном случае - false.

{{ store.loading$ | async | json }}
0 голосов
/ 29 мая 2020

Я бы настроил иначе

export class StoreService {
   public isLoading$ = new BehaviourSubject(true);

   constructor(protected readonly userStore: UserStoreService, protected readonly chatStore: ChatStoreService) {}

  create(): void {
    this.userStore.setAll();
    this.chatStore.setAll();
    this.load();
  }

  load(): void {
    const isLoading = new BehaviorSubject(true);

    timer(1000).subscribe(() => {
      combineLatest([this.userStore.loading, this.chatStore.loading])
        .pipe(filter(([userLoading, chatLoading]) => !userLoading && !chatLoading),takeWhile(([userLoading, chatLoading]) => !userLoading && !chatLoading))
     .subscribe(() => this.isLoading$.next(false));
    });
  }
}

тогда в вашем AppComponent

export class AppComponent implements OnInit {
  constructor(private store: StoreService) {}

  ngOnInit(): void {
    this.store.create();
  }
}

{{ store.isLoading$ | async | json }}
...