如何等待可观察对象中的异步函数?

How wait for a async function in an observable?

我将有一个 angular 服务,其功能 getTimeLinePosts 从服务器获取 JSON。在 timeline-page.ts 组件中,我将订阅该功能。向服务器发送请求时,我需要发送先前缓存响应的日期(使用 ionic cache)以检查是否有新数据。问题是 const date returns 一个承诺而不是一个值。我将无法使用 async getTimeLinePosts,因为时间线中的订阅 - page.ts。建议我如何等待日期再返回 loadFromDelayedObservable?

getTimelinePosts(
    limit: number = 25,
    offset: number = 0,
    type: string = "",
    group: number = null
) {
    let cacheKey = `api/timeline?l=${limit}&o=${offset}&t=${type}&g=${group}`;

    // How wait for this value before fire request
    const date = this.getCachedItem(cacheKey);

    let request = this.http.post(cacheKey, { headers: HEADER.headers , params: JSON.stringify({ dateUpdated: date }) } );
    let groupKey = "timeline";
    let ttl = 60 * 60 * 1;
    let delayType = "none";

    return this.cache
        .loadFromDelayedObservable(url, request, groupKey, ttl, delayType)
        .pipe(map((result) => result));

}

    async getCachedItem(cacheKey){
        let data = await this.cache.getItem(cacheKey)
        .catch(() => {
            console.log("Oh no! My promise is expired or doesn't exist!");
        });
        return await data.data.dateUpdated;
    }
this.TimelineService.getTimelinePosts(limit, offset, type, group).subscribe(
            (data) => {
                this.setTimelineData(data);
            }
        );

您可以使用 observables - 特别是 mergeMap/flatMap,这类似于一个接一个地发送两个请求,其中第二个请求依赖于第一个:

getTimelinePosts(
    limit: number = 25,
    offset: number = 0,
    type: string = "",
    group: number = null
) {
    let cacheKey = `api/timeline?l=${limit}&o=${offset}&t=${type}&g=${group}`;

    this.getCachedItem(cacheKey)
        .pipe(mergeMap((date) => {
            let request = this.http.post(cacheKey, { headers: HEADER.headers , params: JSON.stringify({ dateUpdated: date }) } );
            let groupKey = "timeline";
            let ttl = 60 * 60 * 1;
            let delayType = "none";
        
            return this.cache
                .loadFromDelayedObservable(url, request, groupKey, ttl, delayType)
                .pipe(map((result) => result));
        }));
}

这看起来像是结合可观察对象和承诺的典型案例。我会坚持将承诺转换为可观察的,这样我们就可以利用它的许多优势。

您可以使用 RxJS from 函数将 promise 转换为 observable。然后你可以使用像 switchMap 这样的高阶映射运算符来从一个可观察到的映射到另一个。

尝试以下方法

import { from } from 'rxjs';
import { switchMap } from 'rxjs/operators';

getTimelinePosts(
    limit: number = 25,
    offset: number = 0,
    type: string = "",
    group: number = null
) {
    let cacheKey = `api/timeline?l=${limit}&o=${offset}&t=${type}&g=${group}`;

    return from(this.getCachedItem(cacheKey)).pipe(
        switchMap(date => {
            let request = this.http.post(cacheKey, { headers: HEADER.headers, params: JSON.stringify({ dateUpdated: date }) });
            let groupKey = "timeline";
            let ttl = 60 * 60 * 1;
            let delayType = "none";

            return this.cache
                .loadFromDelayedObservable(url, request, groupKey, ttl, delayType)
                .pipe(map((result) => result));
        })
    );
}