fromEvent / fromEventPattern-如果取消订阅的管道具有startWith,则不会在取消订阅时进行删除

时间:2019-05-03 12:45:27

标签: rxjs

我正在使用fromEvent,但是我切换到fromEventPattern,因此可以console.log进行故障排除。我看到当我unsubscribe()时,仅调用第一个fromEventPattern删除方法。有谁知道为什么window.remveEventListener('online')offline的删除处理程序没有被调用?

如果我将startWith(window.navigator.onLine)中的.pipe删除,则可以使用,但是至少需要其中一个使用startWith(window.navigator.onLine)

这是我的管道:

pipeline$ = combineLatest(
    merge(
        fromEventPattern(
            handler => {
                console.log('adding io.socket.disconnect');
                io.socket.on('disconnect', handler);
            },
            handler => {
                console.log('removing io.socket.disconnect');
                io.socket.off('disconnect', handler);
            },
        ).pipe(
            mapTo(false),
            tap(() => this.setState({ isConnected: false })),
        ),
        this.isConnectedSubject.pipe(
            tap(isConnected => this.setState({ isConnected })),
            startWith(io.socket.isConnected())
        )
    ),
    merge(
        fromEventPattern(
            handler => {
                console.log('adding window.online');
                window.addEventListener('online', handler, false);
            },
            handler => {
                console.log('removing window.online');
                window.removeEventListener('online', handler, false);
            }
        ).pipe(
            tap(() => console.log('online')),
            mapTo(true),
            tap(() => this.setState({ isOnline: true })),
            startWith(window.navigator.onLine)
        ),
        fromEventPattern(
            handler => {
                console.log('adding window.offline');
                window.addEventListener('offline', handler, false);
            },
            handler => {
                console.log('removing window.offline');
                window.removeEventListener('offline', handler, false);
            }
        ).pipe(
            tap(() => console.log('offline')),
            mapTo(false),
            tap(() => this.setState({ isOnline: false })),
            startWith(window.navigator.onLine)
        )
    )
).pipe(
    switchMap(([ isConnected, isOnline, ...rest ]) => {
        console.log('isConnected:', isConnected, 'isOnline:', isOnline, 'rest:', rest);
        console.log(!isConnected && isOnline ? 'RE-CON now' : 'DO NOT re-con');
        return !isConnected && isOnline
            ? defer(() => connectSocket()).pipe(
                retryWhen(error$ =>
                    error$.pipe(
                        tap(error => console.log('got socket connect error!', error.message)),
                        delayWhen((_, i) => {
                            const retryIn = 10000;
                            this.setState({
                                retryAt: Date.now() + retryIn
                            });
                            return timer(retryIn);
                        })
                    )
                ),
                tap(() => isConnectedSubject.next(true))
            )
            : EMPTY;
    }),
    takeUntil(mSessionSubject.pipe(
        filter(action => action.type === 'LOGOUT'),
    ))
);

我这样订阅:

const sub = pipeline$.subscribe();

然后我这样退订:

sub.unsubscribe();

调用此取消订阅后,我没有看到online / offline删除方法触发器。

1 个答案:

答案 0 :(得分:0)

您是否在取消订阅之前检查是否已定义订阅? 像

if (sub !== undefined) {
  sub.unsubscribe();
}

因为您可能会在sub发出任何数据之前退订It's not recommended to use unsubscribe ,但是您可以使用take(n), 改为takeWhile(predicate)first()first(predicate)