首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >单史诗中的多异步操作执行顺序

单史诗中的多异步操作执行顺序
EN

Stack Overflow用户
提问于 2019-09-12 19:13:36
回答 1查看 149关注 0票数 0

我正在尝试设置loginEpic,这是当用户登录时发生的。这就是逻辑流应该如何工作的方式:

史诗应该从LOGIN_REQUEST动作开始。一旦成功完成登录承诺,应该使用SYNC_USER_REQUEST操作获取用户信息(这基本上是另一个史诗,因为这在最初进入站点获取用户信息或重定向登录时也会被调用)。一旦成功完成(承诺和成功/失败调用在syncUserEpic中被处理),SYNC_USER_SUCCESS应该在loginEpic中被捕获,LOGIN_SUCCESS应该与重定向用户到起始页面的push操作一起被调用。

到目前为止,这就是我所拥有的:

代码语言:javascript
复制
const loginEpic: Types.RootEpic = (action$) => 
    action$.ofType("LOGIN_REQUEST").pipe(
        switchMap(({ payload }) => 
            from(membershipService.login(payload.username, payload.password)).pipe(
                switchMap((response) => [
                    syncUser.request(), 
                    action$.ofType("SYNC_USER_SUCCESS").pipe( // I think this is the problem
                        filter(isActionOf(syncUser.success)),
                        map(r => login.success(response))
                    )
                ]),
                takeUntil(action$.ofType(["LOGOUT_REQUEST", "LOGIN_CANCEL"])),
                catchError(error => of(login.failure(error))),
                endWith(push("/"))
            )
        )
    )

但我得到了

动作必须是普通的对象。使用自定义中间件进行异步操作。

我还取消了LOGIN_REQUEST/SYNC_USER_REQUESTLOGOUT_REQUESTLOGIN_CANCEL操作,也处理了登录错误(我不确定这里是否也应该处理同步用户错误)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-13 09:31:15

我设法以这样的方式实现了它:

代码语言:javascript
复制
const loginEpic: Types.RootEpic = (action$) =>
    action$.pipe(
        filter(isActionOf(login.request)),
        switchMap(({ payload }) =>
            race(
                from(membershipService.login(payload.username, payload.password)).pipe(
                    mergeMap((token) =>
                        from(membershipService.getUser()).pipe(
                            mergeMap((user) => [syncUser.success(user), login.success(token)]),
                            catchError(error => {
                                // user fetch failed, tell login that user is responsible
                                return of(login.failure(new BaseError("6010", "User sync failed.")));
                            })
                        )
                    ),
                    catchError(error => of(login.failure(error))),
                ),
                action$.pipe(
                    filter(isActionOf(logout.request)),
                    map(() => login.cancel()),
                    take(1)
                )
            )

        )
    )

根据它的工作原理,race实际上是在运行整个第一个块(不仅仅是外部membershipService.login,还有logout.request操作)。我没有意识到这一点,我想我需要membershipService.getUser的另一个race条件,因为我需要的是logout.request终止整个进程(即使login成功并且进程处于获取用户的中间)。就我所能测试的情况而言,它正如期而至。

如果有人有任何想法,改进,修正,或反模式的观察,请告诉我。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57913178

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档