Cześć!
Przychodzę z problemem jak dla mnie nietrywialnym, nieźle mi ryje czapkę. Małe założenia na początek.
Korzystam z ts, puppeteera oraz rxjs'a (ten ostatni to mój wybór może będziecie mieć lepsze propozycje). Odpalam chroma, wchodzę na jakąś stronę z tabelką danych, znany scenariusz, scroll w dół i leci request po więcej danych. Aby pobierać te dane nasłuchuje na response z konkretnym url'em. Scenariusz jest taki, że po tym jak sobie przescrolluję trochę danych to mogę stwierdzić, że już więcej nie potrzebuję. I pytanie jak to zakończyć. Na ten moment postawiłem na Observable. Problem jest taki że decyzja o zakończeniu subskrypcji leży po stronie subskrybenta (który de facto tylko dostaje dane), a nie źródła.
Ogólnie już ten problem rozwiązałem; subskrybent oraz źródło danych mogą mieć dostęp do tej samej referencji obiektu, ale to nieczyste rozwiązanie. Myślałem również aby sprawdzenie czy dane mnie interesują zamknąć w jednym scope'ie ze źródłem. Podsyłam mocno poglądowy kodzik.
import {Page} from "puppeteer";
import {Observable} from "rxjs";
const prepareEnv = async (): Promise<{ Browser, Page }> => {
//....
};
const goToPageWithData = async (page: Page): Promise<void> => {
//long process
};
const subscribe = (page: Page, subscriber) => {
page.on(`response`, async response => {
if (!response.meetsConditions()) {
return;
}
const data = await response.json();
subscriber.next(data);
});
};
const createSource = async (page: Page): Promise<Observable<any>> => {
await goToPageWithData(page);
return new Observable<any>(subscriber => {
subscribe(page, subscriber);
setInterval(() => {
page.evaluate(() => {
//scrolowanie strony
//tutaj powinienem mieć możliwość odebrania sygnału że trzeba przestać scrolować
// + subscriber.close()
});
}, 3000);
});
};
(async () => {
const { browser, page } = await prepareEnv();
const source = await createSource();
source.subscribe({
next(data) {
//tu mogę sprawdzić czy interesuje mnie pobieranie danych dalej
}
})
});
Zastanawiam się jakiego podejścia się tutaj trzymać. Może podejść do problemu obiektami które będą trzymać state? Bardziej funkcyjnie/reaktywnie?