Я использую Angular 6 с RxJS 6.2.2 и RxJS Compact 6.2.2.

У меня есть код для вызова моей службы api для загрузки некоторых записей, а именно:

this.route.params
  .flatMap((params: Params) => {
    if (!params['id']) {
      return Observable.throwError('Id is not specified.');
    }

    this.itemId = params['id'];
    this.isEditMode = true;
    this.loadCategoryGroupCondition = new LoadCategoryGroupViewModel();
    this.loadCategoryGroupCondition.id = [this.itemId];
    this.loadCategoryGroupCondition.pagination = new Pagination();

    return this.categoryGroupService
      .loadCategoryGroup(this.loadCategoryGroupCondition);
  })
  .subscribe(
    (loadCategoryGroupResult: SearchResult<CategoryGroup>) => {
      console.log(loadCategoryGroupResult);
    },
    () => {},
    () => {
      console.log('Completed')
    });

Приведенный выше код может распечатать список моих товаров, возвращенных моей службой api. Это означает, что был вызван onSuccess.

Но полный метод запущен. Что не так с моим кодом?

Спасибо,

1
Redplane 23 Сен 2018 в 12:18

1 ответ

Лучший ответ

Как обсуждалось, оператор flatMap сам по себе не завершает наблюдаемое исходное состояние. Вы используете this.route.params в качестве наблюдаемого источника, который является долгоживущим - он никогда не завершается сам по себе.

Чтобы получить уведомление complete, вы можете использовать такой оператор, как take. Он повторно выдаст количество элементов, которые вы передаете в качестве параметра, и затем завершится. Например, если вы просто хотите получить текущий маршрут и не заинтересованы в дальнейших уведомлениях о наблюдаемом источнике, используйте take(1), например:

this.route.params
  .take(1)
  .flatMap((params: Params) => {

Также обратите внимание, что рекомендуемый способ сделать это в RxJS 6+ - использовать конвейерные операторы. Это выглядело бы так:

this.route.params.pipe(
  first(),
  mergeMap((params: Params) => {
  ...
})

Я также заменил операторы на более новые рекомендуемые варианты.

2
ggradnig 23 Сен 2018 в 10:06