我有一个问题,这是简单的业务逻辑流程:
检查多个部门,部门和员工关系中的员工是否在缓存中,首先检查缓存中是否存在关系,如果存在,检查是否存在 员工属于它,如果不在缓存中,则从数据库中获取,并检查员工关系,然后将部门信息保存到缓存中。
这是代码:
public Observable isEmployeeInDepartment(List<Long> departmentIds, long employeeId){
//this observable will resolve twice, and cause unnecessary cache access
Observable departmentInfoExsitInCache= checkDepartmentInfoFromCache(...).share();
Observable departInfoNotInCache = departmentInfoExsitInCache.filter(...);
//this observable will resolve twice, and cause unnecessary database access
Observable departmentInfoFromDb=departInfoNotInCache.flatMap(departmentIds->checkFromDb()).share();
Observable<Long> saveResult=departmentInfoFromDb.flatMap(departmentInfo->saveToCache());
Observable<Long> departInfoInCache = departmentInfoExsitInCache.filter(...);
return departInfoInCache.check(userId).merge( departmentInfoFromDb.check(userId)).doOnCompleted(saveResult.subscribe());
}
问题是,一旦客户端方法订阅,departmentInfoExsitInCache和saveResult将被解析两次。
我发现一旦删除了保存订阅代码.doOnCompleted(saveResult.subscribe()),它将变为正常并且只解析一次。这段代码有什么问题吗?
答案 0 :(得分:0)
你在这里滥用分享。
问题是share()
在这种情况下无法帮助您。 share()
实际上publish().autoConnect()
意味着保持对流的单一订阅,因此再次调用subscribe将不会再次调用订阅逻辑,而只是将您连接到现有流。
但是,在从共享流中取消订阅的所有订阅者之后,Observable将取消订阅,这意味着当您再次调用subscribe()
时,您将调用订阅逻辑并再次调用DB / Cache。 / p>
因此,您正在做的是在取消订阅后再次订阅共享运营商。 (在doOnCompleted()
中),这将导致departmentInfoFromDb
和departmentInfoExsitInCache
再次订阅并转到DB / Cache。
考虑使用cache()/reply()
运算符在订阅之间持久保存从DB / Cache获取的值。