Вопрос 1
combineLatest(this.layerService.layersData$, this.displayService.displayData$, this.dataSource.data$,
(layer, display, data) => ({ layer, display, data }))
.pipe(
skipWhile(({ layer, display, data }) =>
_.isEmpty(layer) || _.isEmpty(display) || _.isEmpty(data)),
takeWhile(() => this.cacheService.isDirty()),
sample(interval(2000)),
map(result => {
const layerFiltered = result.layer.filter(ly => result.display.findIndex(d => d.id === ly.id) !== -1);
return { ...result, layer: layerFiltered };
})
)
.subscribe(result => {
console.log(result);
});
Я хочу избежать выборки на самом первом излучении и использовать выборку после этого.
Самым первым излучением, я имею в виду, этобыл в состоянии добраться до функции карты.Может ли это быть достигнуто без использования внешней локальной переменной?
Вопрос 2
ngOnInit() {
this.displayService.displayData$.delay(500).take(1).subscribe(data => this.displayMeta = data);
this.layerService.getLayerData()
.subscribe(layers => {
this.layers = layers;
});
}
Я хочу подписаться на layerService, чтобы дождаться завершения displayService, я могу поставить layerServiceлогика подписки внутри метода подписки displayService, но это не кажется хорошим решением проблемы.
Я хочу, чтобы this.displayService ....... код был синхронным.Это также требуется один раз, а не оператор take (1).
Вопрос 3
dirty = {};
fetchedData = {};
reportData$ = new BehaviorSubject({});
constructor(private dataSourceService: DataSourceService, private someService: SomeService) {
const dataFetch$ = this.dataSourceService.data$
.pipe(
tap(dList => {
// update dirty by comparing dList, if this.dirty has 3 keys and dList have two item then this.dirty length will be two
this.dirty = dList.reduce((acc, et) => ({ ...acc, [et.id]: _.get(this.dirty, et.id, true) }), {});
}),
filter(dList => !_.isEmpty(dList)),
map(dList => _.filter(dList, dL => this.dataSourceService.dirty[dL.id])),
concatMap(dList => from(dList)),
flatMap(dItem => this.someService.getDataFromApi(dItem), (item, data) => {
return { id: item.id, data };
}),
tap(({ id, data }) => {
this.fetchedData[id] = data;
this.dirty[id] = false;
this.dataSourceService.resetDirty(id);
})
);
dataFetch$.merge(this.dataSourceService.data$)
.subscribe(() => {
this.fetchedData = _.pickBy(this.fetchedData, (__, key) => _.has(this.dirty, key));
this.reportData$.next(this.fetchedData);
});
}
Метод подписки должен вызываться, даже если фильтрвернуть ложьПроблема с вышеуказанным подходом состоит в том, что подписка будет вызываться дважды.
Если dList пуст, dataFetch $ не вызывается, поэтому подписка вызывается один раз, но если она не пуста, то подписка вызывается дважды.
Конструкция такова: если элемент удаляется из this.dataSourceService.data $ один за другим и, наконец, this.dataSourceService.data $ .length становится 0, наблюдаемая цепочка не достигнет подписки, в этом случае также сделайте это.fetchedData = empty
Поскольку элемент из dataSourceService.data $ удаляется, соответствующий элемент из this.fetchedData должен быть удален, я не знаю, какой элемент удален, поэтому грязный флаг, обратите внимание на первую операцию касания.В подписке dirtyList используется для обновления fetchedData.