Игнорировать промежуточные выбросы отмененных наблюдаемых - PullRequest
0 голосов
/ 04 июля 2019

Пользователи могут запустить поиск, где я объединяю переменное число HTTP-запросов, используя такой подход: Angular 2 объединяет три http-вызова с flatMap?RxJs? .

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

  • Пользователь начинает Поиск A
    • Поиск Часть 1 начинается
    • Поиск Часть 1 заканчивается
    • Поиск Часть 2 начинается
  • Пользователь начинает Поиск B
    • Поиск B, часть 1 начинается
    • Поиск B, часть 1 заканчивается
    • Поиск B завершается
  • Пользователь видит результаты для B (B part 1)

Самое близкое, что я могу найти - switchAll , который отменяет / отменяет часть 2,но я получаю часть 1, смешанную с результатами.Примечание: включается только последняя законченная деталь, поэтому, если пользователь начинает новый поиск во время детали n, то включается только n - 1 (для n > 1), а n - 2 и предыдущие отбрасываются.

Итак, мои вопросы:

  • Почему промежуточные результаты работают вместе?
  • Как добиться желаемого эффекта?
    • Можно ли отбросить промежуточные результаты предыдущего поиска?
    • Можно ли рассматривать поиски как единичные выбросы?

Код, который я получил, немного запутан, но вот грубая упрощенная схема:

// User fires this event.
startSearch() {
    this.searchSubject(getUsersCriteria());
}

ngOnInit() {
    // The event is transformed into a search request.
    this.searchSubject
        .asObservable()
        .pipe(
            map((criteria) => search(criteria)),
            switchAll(), // FIXME Not sufficient.
            tap((results) => this.setResults(results))
        )
        .subscribe();
}

/**
 * Execute the search and return the results.
 **/
search(criteria): Observable<Result[]> {
    return this.http.get('https://proprietary.com/endpoint', criteria)
        .pipe(flatMap((results) => {
            // Process results. Conditionally continue.
            if (done()) return of(results);
            else return search(criteria.nextCriteria())
                .pipe(map((moreResults) => [...results, ...moreResults]));
        });
}

Примечание. В настоящее время используется RxJS 6.

Ответы [ 2 ]

0 голосов
/ 12 июля 2019

Слишком усердный перехватчик HTTP возвращал результаты первого (отмененного) поиска, а также (ошибочно) второго поиска.

Перепроверьте HTTP-перехватчики.

0 голосов
/ 10 июля 2019

Не уверен, что это работает, но вы можете попробовать передать дополнительный параметр в качестве начального значения для вашего набора результатов. Все, когда searchSubject срабатывает, новый пустой набор результатов [] будет передан в рекурсивную цепочку.

ngOnInit() {
    // The event is transformed into a search request.
    this.searchSubject
        .asObservable()
        .pipe(
            switchMap((criteria) => search(criteria,[])),
            tap((results) => this.setResults(results))
        )
        .subscribe();
}


/**
 * Execute the search and return the results.
 **/
search(criteria,resultSet): Observable<Result[]> {
    return this.http.get('https://proprietary.com/endpoint', criteria)
        .pipe(flatMap((results) => {
            // Process results. Conditionally continue.
            if (done()) return of(resultSet);                
            return search(criteria.nextCriteria(),resultSet.concat(results))   
        });
}
...