Как вызвать несколько subject.next (), которые зависят друг от друга один за другим? [RxJS] - PullRequest
0 голосов
/ 04 ноября 2019

У меня есть модальная диалоговая служба. Каждый экземпляр диалогового окна имеет SubClose Subject, на который этот пользователь API может подписаться, чтобы сделать что-то после закрытия диалогового окна.
Теперь я хотел бы добавить тему beforeClose, но я не уверен, как связать / скомпоновать его впоток моих наблюдаемых.

Закрытие диалогового окна также выполняется асинхронно.

Это выглядит примерно так:

const asyncSimulation = val =>
  new Promise(resolve => resolve(val));

class DialogService {
  dialogs = [];

  open(text) {
    const afterClose = new rxjs.Subject();
    const onClose = new rxjs.Subject();
    const beforeClose = new rxjs.Subject();

    let dialog = new ModalDialog(text, onClose, afterClose, beforeClose);
    this.dialogs.push(dialog);

    onClose.subscribe(result => {
      this.remove(dialog).subscribe(() => {
        console.log("Closed " + result);
        afterClose.next(result);
        afterClose.complete();
      })
    })

   return dialog;
  }
  
  remove(dialog) {
    return rxjs.of(1)
  }
}

class ModalDialog {
constructor(text, onClose, afterClose, beforeClose) {
  this.text = text;
  this.afterClose = afterClose;
  this.beforeClose = beforeClose;

  //private:
  this.onClose = onClose;
}

close(result) {
  this.onClose.next(result);
}

}

let dialogService = new DialogService();

let firstModal = dialogService.open("Modal 1");
let secondModal = dialogService.open("Modal 2");

secondModal.afterClose.subscribe((result) => console.log("After Close " + result));
secondModal.beforeClose.subscribe((result) => console.log("Before Close " + result));

firstModal.close("Modal 1");
secondModal.close("Modal 2");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.3/rxjs.umd.js"></script>

Я уже читал на SO, что вызов подписки внутри подписки - плохая практика, но я не уверен, как написать правильный поток, который:

Вызывает следующие функции моих Observables в следующем порядке: onClose beforeClose remove afterClose

Должен ли я вернуть observable из beforeClose.next () и подписаться на него? Это не правильно ...

Как насчет этого?

  onClose.pipe(mergeMap(() => {
            return beforeClose
        })).subscribe((result => {
         this.remove(dialog).subscribe(() => {
            console.log("Closed " + result);
            afterClose.next(result);
            afterClose.complete();
  })
})

1 Ответ

0 голосов
/ 05 ноября 2019

beforeClose должен быть вызван первым действительно, и вы можете захотеть отменить закрытие, просмотрев возвращаемое значение из beforeClose stream

beforeClose.pipe(tap(close=>
   close?onClose.next():null)
).subscribe()

onClose.pipe(
  mergeMap(()=>this.remove(dialog)),
  tap(()=>afterClose.next())
).subscribe()
...