添加事件监听器,并使用`scan`保持简化状态,然后删除事件监听器

时间:2019-04-27 21:35:56

标签: rxjs

我正在此沙盒上工作-https://stackblitz.com/edit/rxjs-g7msgv?file=index.ts

我想做的是:

1)等待onLogin事件

2)登录后,我想connectSocket(),每当套接字断开连接且应用程序在前台时,我都想重新connectSocket()。 (在沙盒中,我将connectSocket()设置为仅等待5秒的承诺)

3)我要重复步骤2,直到出现onLogout事件

我在此处编写了此代码,请查看沙箱并通过按“ onLogin”按钮开始操作。

fromEvent(document, 'onLogin')
    .pipe(
        switchMap(() =>
            of({ isDisconnected: true, isInForeground: true }).pipe(
                mergeMap(data =>
                    concat(
                        fromEvent(document, 'onDisconnect').pipe(
                            mergeMap(() =>
                                data.isDisconnected = true
                            )
                        ),
                        fromEvent(document, 'onAppStateChange').pipe(
                            mergeMap(({ detail:{ state } }) =>
                                data.isInForeground = state === 'foreground'
                            )
                        ),
                    ).pipe(
                        mergeMap(({ isDisconnected, isInForeground }) => {
                            if (isDisconnected && isInForeground) {
                                return flatMap(() => connectSocket());
                            } else {
                                return EMPTY;
                            }
                        })
                    )
                ),
                takeUntil(fromEvent(document, 'onLogout'))
            )
        )
    )
    .subscribe(console.log);

我使用switchMap是因为在运行时,我不希望任何其他登录事件重新启动另一个流程。

我无法正常工作。我是rxjs的新手。

1 个答案:

答案 0 :(得分:1)

使用startWith初始化值,并且combineLatest将在触发任何一个事件时触发。

fromEvent(document, 'onLogin').pipe(
    switchMap(() =>
        combineLatest(
            fromEvent(document, 'onDisconnect').pipe(
                mapTo(true),
                startWith(true)
            ),
            fromEvent(document, 'onAppStateChange').pipe(
                map(e => e.detail === 'foreground'),
                startWith(true),
            )
        ).pipe(
            mergeMap(([isDisconnected, isInForeground]) =>
                isDisconnected && isInForeground ? connectSocket() : EMPTY
            ),
            takeUntil(fromEvent(document, 'onLogout'))
        )
    )
)