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