[英]Angular 5: Returning an Observable from a function
在過去,我會定義一個新的Promise
,將其推遲,然后在我的函數完成時解決。 現在我發現自己處在需要從函數返回Observable
的情況下,並且我想確保自己在Angular 5
上下文中正確設置了它。
測試功能,工作正常:
getTreeViewChildren(currNode: any, nodeType: string, nodeTypeEnum: number = 0, nested: boolean = true) : Observable<any> { let treeObs: Observable<any>; treeObs = new Observable(obs => { this.siteConfigService.getHostAccessPoints().subscribe(data => { let hostAccessPoints = JSON.parse(data); let accPointTree = this.findChildNodes(currNode, hostAccessPoints, nested); obs.next(accPointTree); obs.complete(); }); }); return treeObs; }
從我的NG組件中,我成功訂閱了:
this.configService.getTreeViewChildren(this.selectedTreeViewItem, type, nodetype, true).subscribe(tree =>{ let theTree = tree; });
但是,實函數具有更多的檢索邏輯。 按照上面的測試功能設置Observable
的正確方法是什么? 完全相同的模式,只是將所有代碼包裝在treeObs = new Observable(..)
?
getTreeViewChildNodes(currNode: any, nodeType: string, nodeTypeEnum: number = 0, nested: boolean = true): Observable<any> { let hosts; let locations; let hostAccessPoints; let treeResult: Observable<any>; if (nodeTypeEnum === NodeType.Location) { // more code.. let someTree = getStuff(); return someTree; } if (nodeTypeEnum === NodeType.Host) { // more code.. let someTree = getStuff(); return someTree; } if (nodeTypeEnum === NodeType.HostAccessPoint) { let accPointTree; if (sessionStorage["hostAccessPoints"]) { // more code.. let someTree = getStuff(); return someTree; } else { this.siteConfigService.getHostAccessPoints().subscribe(data => { // more code.. let someTree = getStuff(); return someTree; }); } } if (nodeTypeEnum === NodeType.HostStorage) { // TO DO } }
****更新(下面的基於Observable.of()
建議答案):
// Builds hierarchical treeview data getTreeViewChildNodes(currNode: any, nodeType: string, nodeTypeEnum: number = 0, nested: boolean = true): Observable<any> { let hosts; let locations; let hostAccessPoints; if (nodeTypeEnum === NodeType.Location) { if (sessionStorage["locations"] != null && sessionStorage["locations"] != "undefined") { locations = JSON.parse( sessionStorage.getItem('locations') ); } // find child nodes let locationTree = this.findChildren(currNode, locations, nested); return Observable.of(locationTree); } if (nodeTypeEnum === NodeType.Host) { if (sessionStorage["hosts"] != null && sessionStorage["hosts"] != "undefined") { hosts = JSON.parse( sessionStorage.getItem('hosts') ); } // find child hosts for current node let hostTree = this.findChildHosts(currNode, hosts, nested); return Observable.of(hostTree); } if (nodeTypeEnum === NodeType.HostAccessPoint) { let accPointTree; if (sessionStorage["hostAccessPoints"]) { hostAccessPoints = sessionStorage.getItem("hostAccessPoints"); accPointTree = this.findChildHostAccessPoints(currNode, hostAccessPoints, nested); return Observable.of(accPointTree); } else { // **** THREW ERROR FROM CALLER 'Cannot read property 'subscribe' of undefined****` /*this.siteConfigService.getHostAccessPoints().subscribe(data => { hostAccessPoints = JSON.parse(data); accPointTree = this.findChildHostAccessPoints(currNode, hostAccessPoints, nested); return Observable.of(accPointTree); });*/ // ** CORRECTED CODE ** return this.siteConfigService.getHostAccessPoints().map(data => { hostAccessPoints = JSON.parse(data); accPointTree = this.findChildHostAccessPoints(currNode, hostAccessPoints, nested); return accPointTree; }); } } }
並且從我的組件代碼中,它引發一個錯誤TypeError: Cannot read property 'subscribe' of undefined
僅在我調用服務的地方TypeError: Cannot read property 'subscribe' of undefined
而服務又依次調用http.get():
this.configService.getTreeViewChildNodes(this.selectedTreeViewItem, type, nodetype, true).subscribe(data => {
this.rebuildNetworkTree(data);
});
大概,您應該使用Subject,就像這樣:
let treeSubj = new Subject<any>();
let treeResult = this.treeSubj.asObservable();
// a lot of code
// need to tick a value in treeResult somewhere - can do this in several places
this.treeSubj.next(yourValue)
// and then somewhere need to get that result
this.treeResult.subscribe(tree => doSomething(tree));
這樣,每次調用treeSubj.next(value)
treeResult
訂閱者都會收到該值。
對於第二個示例要返回的內容,我無法提供足夠的詳細信息,但是第一個示例的更好方法是沒有new Observable(...)
東西。 最好只使用map
運算符來轉換數據。
getTreeViewChildren(currNode: any, nodeType: string, nodeTypeEnum: number = 0, nested: boolean = true): Observable<any> {
return this.siteConfigService.getHostAccessPoints().map(data => {
let hostAccessPoints = JSON.parse(data);
let accPointTree = this.findChildHostAccessPoints(currNode, hostAccessPoints, nested);
return 'test123';
});
}
從評論更新
如果您有一個有時使用異步操作而有時不使用異步操作的函數,則可以將Observable.of()
用於非異步返回:
getTreeViewChildNodes(currNode: any, nodeType: string, nodeTypeEnum: number = 0, nested: boolean = true): Observable<any> {
if (doSynchronousWork) {
// more code..
let someTree = getStuff();
return Observable.of(someTree);
}
if (doAsynchronousWork) {
return this.siteConfigService.getHostAccessPoints().map(data => {
// more code..
let someTree = getStuff();
return someTree;
});
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.