Не понимаю, почему мой оператор withLatestFrom запускается - PullRequest
0 голосов
/ 04 мая 2018

Я медленно начинаю понимать rxjs, но время от времени я сталкиваюсь с вещами, которые меня озадачивают.

В данном случае речь идет об операторе withLatestFrom. Оператор rxjs ниже находится в методе OnInit моего углового компонента. Когда экран загружается, я вижу, что вызов API в методе getApiData () выполняется дважды, хотя я уверен, что userEventSubject $ никогда не запускался (вот почему у меня есть первый оператор tap).

Что я ожидаю, так это то, что метод getApiData () вызывается только при вызове userEventSubject $ .next () и никогда при загрузке экрана ...

this.userEventSubject$
    .pipe(
        tap(creditNote => console.log('tapped!')),
        takeUntil(this.ngUnsubscribe$),
        filter(userEventData => this.checkValidity(userEventData)),
        withLatestFrom(this.apiService.getApiData()),
        mergeMap(([userEventData, apiData]) => {
            let modalRef = this.modalService.show(ModalDialogComponent, {
                initialState: { apiData }
            });
            let instance = <ModalDialogComponent>modalRef.content;

            return instance.save.pipe(
                mergeMap((info) =>
                    this.apiService.saveSomeData(userEventData, info).pipe(
                        catchError((error, caught) => {
                            instance.error = error;
                            return empty();
                        })
                    )
                ),
                tap(response => modalRef.hide())
            );
        })
    )
    .subscribe((response) => {
        this.handleResponse(response);
    });

Фиксированная версия:

this.userEventSubject$
    .pipe(
        tap(creditNote => console.log('tapped!')),
        takeUntil(this.ngUnsubscribe$),
        filter(userEventData => this.checkValidity(userEventData)),
        mergeMap(userEventData =>
            this.apiService.getApiData().pipe(
                map(data => {
                    return { userEventData, data };
                })
            )
        ),
        mergeMap(values => {
            let modalRef = this.modalService.show(ModalDialogComponent, {
                initialState: { data: values.apiData }
            });
            let instance = <ModalDialogComponent>modalRef.content;

            return instance.save.pipe(
                mergeMap((info) =>
                    this.apiService.saveSomeData(userEventData, info).pipe(
                        catchError((error, caught) => {
                            instance.error = error;
                            return empty();
                        })
                    )
                ),
                tap(response => modalRef.hide())
            );
        })
    )
    .subscribe((response) => {
        this.handleResponse(response);
    });

1 Ответ

0 голосов
/ 04 мая 2018

Когда вы строите трубу, this.apiService.getApiData() не является функцией стрелки, но выполняется сразу. Неважно, что вызов передан в качестве аргумента. Выражение выполняется как любой другой вызов JS (попробуйте поместить console.log в то же место).

Вы можете сделать .concatMap(userData => this.apiService.getApiData().map(apidata => {userData, apiData})) (или switchMap), но это вызовет API всегда. Я не знаю, что лучше для ваших нужд.

...