import { reduce, filter, map, mapTo } from 'rxjs/operators' import { from, fromEvent, scan, Subscription } from 'rxjs' const button1 = document.getElementById("but1") const button2 = document.getElementById("but2") const button3 = document.getElementById("but3") let click1 = fromEvent(button1, 'click') .subscribe(result => { count3.subscribe(x => p3.innerHTML = `Click count: ${x}`) }) let click2 = fromEvent(button2, 'click')aquí quiero cancelar la suscripción (cuando hago clic en el segundo botón, pero con la oportunidad de suscribirme nuevamente cuando hago clic en el primer botón)
he probado con algo asi
const sub = click1.subscribe(result => { count3.subscribe(x => p3.innerHTML = `Click count: ${x}`) }) let click2 = fromEvent(button2, 'click') sub.unsubscribe()Pero no sé cómo poner sub.unsubscribe() en el botón
let click3 = fromEvent(button3, 'click') let three = click3.pipe(mapTo(1)) let c: number = 0 let count3 = three.pipe(scan((acc, val) => acc + val, c)) const d = document.getElementById("d") const p3 = document.createElement("p") //count3.subscribe(x => p3.innerHTML = `Click count: ${x}`) d?.appendChild(p3)Podemos cancelar la suscripción con el segundo clic del botón y luego, cuando se vuelve a hacer clic en el primer botón, necesitamos borrar cualquier suscripción ya presente, luego reiniciamos la suscripción, finalmente nos suscribimos nuevamente.
Por favor, avíseme si encuentra esta confusión, aclararé sus dudas.
No estoy seguro de lo que está tratando de lograr, pero use el siguiente ejemplo y modifíquelo para su caso de uso.
import { mapTo } from 'rxjs/operators'; import { fromEvent, scan, Subscription } from 'rxjs'; const button1 = document.getElementById('but1'); const button2 = document.getElementById('but2'); const button3 = document.getElementById('but3'); let clickCountSubscription = new Subscription(); let interimValue = 0; const getCount3 = () => { let click3 = fromEvent(button3, 'click'); let three = click3.pipe(mapTo(1)); return three.pipe( scan((acc, val) => { interimValue = acc + val; return acc + val; }, interimValue) ); }; let click1 = fromEvent(button1, 'click').subscribe((result) => { clickCountSubscription.unsubscribe(); clickCountSubscription = new Subscription(); clickCountSubscription.add( getCount3().subscribe((x) => (p3.innerHTML = `Click count: ${x}`)) ); }); let click2 = fromEvent(button2, 'click').subscribe(() => { clickCountSubscription.unsubscribe(); }); const d = document.getElementById('d'); const p3 = document.createElement('p'); d?.appendChild(p3);Nota: Esta respuesta se basa en el diálogo en los comentarios de la pregunta principal. Tomando la pregunta literalmente, esta es una solución peor que la de Narem Murali.
Para hacer esto de una manera más reactiva, puede componer varias transmisiones juntas usando solo una suscripción. Esto simplificará la gestión de la suscripción y ayudará con el anidamiento, pero implicará más lógica de flujo y operadores rxjs.
import { map, fromEvent } from 'rxjs'; import { filter, mergeWith, withLatestFrom } from 'rxjs/operators'; // Get the buttons const startBtn = document.getElementById('start'); const stopBtn = document.getElementById('stop'); const countBtn = document.getElementById('count'); // Setup base input streams (could be done later separated here for clarity) const start$ = fromEvent(startBtn, 'click').pipe(map(() => true)); const stop$ = fromEvent(stopBtn, 'click').pipe(map(() => false)); // Merge base input streams so that you only get one output const shouldTake$ = start$.pipe(mergeWith(stop$)); const count$ = fromEvent(countBtn, 'click').pipe( // listen for the count click withLatestFrom(shouldTake$), // determine what the latest value from the merged stream map(([_, shouldTake]) => shouldTake), // ignore the actual click event and just use shouldTake filter((shouldTake) => shouldTake) // Stop the emission if you shouldn't take it ); // Get the counter span const counterSpan = document.getElementById('current-count'); let count = 0; // Actually subscribe to count and do what you care about when you care count$.subscribe(() => { count++; counterSpan.innerText = count.toString(10); });Para ver esto en funcionamiento, consulte este stackblitz https://stackblitz.com/edit/rxjs-zcbaxz?file=index.ts