RXJS / Angular 6: отменить / сгруппировать несколько запросов в один с тайм-аутом - PullRequest
0 голосов
/ 04 сентября 2018

Мне нужно получить данные о погоде для города по уникальному идентификатору. У API есть свои ограничения, поэтому мне нужно сгруппировать несколько запросов в один.

getWeatherByCityId(cityId: number): Observable<IWeatherData> {
    const cachedWeatherData = this.weatherCache.filter(
        (weatherData: IWeatherData) => weatherData.id === cityId
    );
    this.getDebouncedDataTimer = timer(5000);

    if (cachedWeatherData && cachedWeatherData.length !== 0) {
        return of(cachedWeatherData[0]);
    }

    this.debouncedIds.push(cityId);
    if (this.getDebouncedDataSubscription) {
        this.getDebouncedDataSubscription.unsubscribe();
    }
    this.getDebouncedDataSubscription = this.getDebouncedDataByIds(cityId).pipe(
        delay(5000)
    ).subscribe(data => data);

    return this.getDebouncedDataSubscription;
}

Идея состоит в том, чтобы делать только один запрос после 5000 мс, чтобы получить погоду для нескольких городов одновременно, вместо того, чтобы делать несколько запросов после проверки кэшированных данных.

Таким образом, метод getWeatherByCityId должен вызываться множество раз, а метод getDebounceDataByIds должен вызываться только один раз, чтобы не перегружать API.

Проблема в том, что возврат может быть только Наблюдаемым, но не Подпиской. И я не могу использовать карту внутри трубы, потому что я не могу отписаться в этом случае.

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

private getDebouncedDataByIds(cityId: number) {
    return this.getWeatherByCityIds(debouncedIds).pipe(
        map((weatherDataMultiple: HttpResponse<IWeatherDataMultiple>) => {
            if (weatherDataMultiple.status === 200) {
                this.weatherCache.push(...weatherDataMultiple.body.list);

                return weatherDataMultiple.body.list.filter(
                    (weatherData: IWeatherData) => weatherData.id === cityId
                )[0];
            }
        })
    );
}

1 Ответ

0 голосов
/ 04 сентября 2018

Есть несколько способов сделать это. Вы можете отобразить его вне функции или внутри, как вы это сделали. Но идея состоит не в том, чтобы подписаться внутри функции. Вы можете вернуть Observable и вызвать подписку в вызывающем методе. Observable вернет объект подписки, который вы можете отменить позже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...