因此,我对角度以及一般的可观察性都很陌生。我知道如何处理承诺,但我希望对Observable方面更加满意。
我会尽量保持简短,但这是设置:
为了减少对服务器的调用量,我创建了一个包服务,它基本上将多个请求打包到一个请求中。
如果某个组件的缓存不是最新的,则会要求多个数据服务刷新其商店。需要服务器更新的每个数据服务都会向包添加请求。准备好后,组件将包发送到包服务,然后包服务将请求发送到服务器。
当服务器回复数据时,我需要每个数据服务使用与其单个请求相关的新数据更新其商店,然后通知组件所有内容都已完成。
这是我如何用承诺做到的:
1)组件从每个所需的数据服务构建一个包。
2)组件将其发送到返回promise的包服务。
3)包服务发送请求。
4)当服务器回复时,包服务会将响应分派给包中注册的每个数据服务。
5)只有当每个涉及的数据服务都更新其商店时,包服务才会解除其承诺。
6)该组件处理已解决/拒绝的承诺。
因此,尝试将此转换为可观察的模式,我得到了这个:
组件:
let thePackage = this.packageService.createPackageInstance();
this.service1.loadData( thePackage );
this.service2.loadData( thePackage );
this.packageService.sendPackage( thePackage ).subscribe( () => console.log("Success"), (err) => console.error( err ) );
Service1和Service2:
loadData( thePackage: Package ) {
let needUpdate = this.GetCacheIsUpToDate();
if( needUpdate ) {
let params = {
"param1": true
};
//This would return a promise in a promise chain pattern.
let callback = ( ( response:any ) => {
//[...]
//Do update the data store and notify subscribers.
return Promise.resolve(); //The only way I know to make it work.
});
this.packageService.createRequest( thePackage, 100, 1, params, callback );
}
}
PackageService:
createPackageInstance(): Package {
return new Package({/* Some params */});
}
createRequest( thePackage:Package, theModule:number, operation:number, params:any, callback:Function ):void {
let data = JSON.stringify( params );
let request = new Request({
"id": Utils.generateGUID(),
"theModule": theModule,
"operation": operation,
"data" : data,
"callback": callback
});
thePackage.requests.push( request );
}
sendPackage( thePackage ): Observable<PackageResponse>{
//Assume some variables like 'someUrl' to be setup
//[...]
let httpObs = this.http.post( someUrl, formData, someOptions ).map( response => {
return response.json();
});
return httpObs.flatMap( ( response ) => {
let pAll = [];
thePackage.requests.forEach( request => {
pAll.push( request.callback( response ) );
});
return Observable.fromPromise( Promise.all( pAll ) ); //This is really ugly
});
}
编辑:编辑了一些代码,以显示我目前使用promises的版本。
答案 0 :(得分:0)
很抱歉,如果这个答案不够完整 - 我没有太多时间去讨论太多细节,但是它太长了,不适合评论。
现在,您需要获取在callback
中为来自服务器的每个数据定义的原始createRequest
。对于基于承诺的解决方案,您应该采用类似的方法,对吗?但这不是太多Rx ......
我要做的是让createRequest
返回服务可以订阅的可观察对象。在createRequest
里面,这个可观察的引擎盖是Rx.BehaviorSubject
:这是一个观察者也是一个观察者,所以每当你在它上面调用.next(message)
时,该主题的下标将收到该消息。然后将此主题存储在包中。
然后,您不必在发出请求后调用回调,而是使用请求的相关数据调用刚存储的主题.next()
。我之后立即调用.complete()
,因此流被处理掉(假设我们不再接收该流,这似乎就是这种情况)
请记住,不鼓励使用Rx.BehaviourSubject
,因为通常有更好的方法来处理这些情况,但在这种情况下我找不到更好的选择(可能有,但我'我不确定)