具有RXjs的Angular2嵌套解析器存储竞争条件

时间:2017-04-15 11:48:59

标签: angular rxjs angular2-routing angular2-services

我又回到了有趣的困境。我正在构建angular2应用程序并使用RXjs可观察数据存储来为我的应用程序提供数据。即在启动时,如果用户已登录,角色中的应用程序解析器将获取登录的用户数据,然后将其推送到商店,然后商店将数据反馈到只有登录用户才能看到的应用程序部分。这意味着,例如,用户通过身份验证的JWT令牌也存在于商店中。

路由示例

{
    path: '',
    resolve: {
        _: AppResolverService
    },
    children: [
        path: 'subnav',
        resolve: {
            _: SubnavResolverService
        }
    ]
}

观察旋转变压器的嵌套方式,其中

AppResolverService

如果用户已登录,则获取JWT令牌和其他用户数据,并将其发送到会话存储数据服务。否则,用户将被重定向到登录。

代码示例:

let resolverObservable = this._sharedOrchestrationService.getLoggedInUser();
resolverObservable
    .subscribe( (res:UserModel) => {
        this._sessionStoreService.setLoggedInUser( res )
});

return resolverObservable;

SubnavResolverService

从会话商店数据服务中获取用户凭据

代码示例:

let ret = this._dashboardOrchestrationService.getUserListings( 
    this._sessionStoreService.loggedInUserLastValue.id 
);

SessionStore

代码示例:

setLoggedInUser( _loggedInUser: UserModel ) : Observable<UserModel> { 
    this._loggedInUser.next( _loggedInUser );
    return this._loggedInUser.asObservable();
}

问题官员?

问题在于,您可以看到会话存储使用可观察的数据服务,并且由于AppResolver正在推送该可观察数据并且它是异步函数,因此SubnavResolverService有50%的可能性开始使用未定义的用户,因为AppResolver已经完成,但SessionStore仍在运行数据推送。

我想在这里实现什么?

AppResolver可以以某种方式延迟,例如。收到用户数据并尝试在sessionStore中设置后200ms?因此,当它结算时,我可以确定用户数据安全地存储在商店中。

1 个答案:

答案 0 :(得分:0)

Welp,我刚刚找到了解决方案。

在返回Observable的AppResolverService中,我添加了一个RXjs delay()修饰符,以便解析器被延迟,但会话存储有时间处理它的更新。

return resolverObservable.delay( (new Date(Date.now() + 200)) );

这会使解析器延迟200ms。

我也对其他解决方案持开放态度,请详细说明!