Obtuve este pseudocódigo para un servicio de raspado que primero explora las URL de paginación y luego las URL de la subpágina en el sitio web "principal" raspado
const pagination = [["url-1", "url-2", "url-3", "url-4"], ["url-5"]]; const timeInterval = 2; sendRequestsInIntervals(pagination, timeInterval ) .pipe() .subscribe({ next(x) { console.log(x); }, error(err) { console.error(err); }, complete() { console.log("done"); sendRequestsInIntervals(resDataArray, timeInterval ).subscribe({ next(x) { console.log(x); }, }); }, });Quiero evitar el anidamiento ya que es una forma incorrecta de usar observables.
¿Hay alguna manera de convertir esto en algo como esto:
sendRequestsInIntervals(pagination, timeInterval ) .pipe( waitUntilCompletes() mergeMap((resDataArray) => { return sendRequestsInIntervals(resDataArray, timeInterval ); }) ) .subscribe({ next(x) { console.log(x); }, error(err) { console.error(err); }, complete() { console.log("done"); }, });Se agregó una pseudo función llamada waitUntilCompletes()
¿Existe tal cosa en rxJS que haga que el observable en mergeMap espere antes de ejecutarse hasta que se complete el observable anterior?
el last operador ignorará todas las emisiones hasta la última al finalizar:
sendRequestsInIntervals(pagination, timeInterval ) .pipe( last(), mergeMap((resDataArray) => { // resDataArray is only the final emitted value from sendRequestsInIntervals() return sendRequestsInIntervals(resDataArray, timeInterval ); }) ) .subscribe({ next(x) { console.log(x); }, error(err) { console.error(err); }, complete() { console.log("done"); }, }); o puede usar reduce para recopilar las emisiones y emitir una vez completadas:
sendRequestsInIntervals(pagination, timeInterval ) .pipe( // this will gather all outter emissions into an array and emit once outter completes reduce((acc, val) => acc.concat(val), []), mergeMap((resDataArray) => { // resDataArray is all values emitted from sendRequestsInIntervals() in an array return sendRequestsInIntervals(resDataArray, timeInterval ); }) ) .subscribe({ next(x) { console.log(x); }, error(err) { console.error(err); }, complete() { console.log("done"); }, });