簡體   English   中英

*RxJs* 如何將多個 ajax 組合到一個不需要序列的 observable

[英]*RxJs* How to combine multiple ajax to one observable that doesn't require sequence

在此處輸入圖片說明

我有兩個 API 來獲取 Angular5 上的菜單數據,但我不知道我是否使用嵌套訂閱,getSecondMenu 函數是 RxJs 的正確方法。 有沒有人有任何想法,以下是預期結果和示例代碼:

console.log: 1. get firstMenuList 2. all done 3. get secondMenu * 3

在 jsFiddle 上打開

 getFirstMenu$() .do(firstMenuList => { console.log('get firstMenuList'); }) .do(firstMenuList => { firstMenuList.forEach(firstMenu => { // nested subscribe : bind to child property, let Angular auto-generate second Menu in HTML getSecondMenu$(firstMenu.ID).subscribe((secondMenu) => { firstMenu.child = secondMenu; console.log('get secondMenu'); }); }) }) .subscribe((menuList) => { console.log('all done' ); }); function getFirstMenu$() { return Rx.Observable.of([{ ID: 'menu1', child: null }, { ID: 'menu2', child: null }, { ID: 'menu3', child: null }, ]); } function getSecondMenu$(menuID) { let source = null; switch (menuID) { case 'menu1': source = [{ ID: 'subMenu1-1', }]; break; case 'menu2': source = [{ ID: 'subMenu2-1', }]; break; default: source = []; break; } const delayTime = ((Math.random() * 20) + 5) * 120; return Rx.Observable.of(source).delay(delayTime); }
 <script src="https://npmcdn.com/@reactivex/rxjs@5.0.0-beta.8/dist/global/Rx.umd.js"></script>


結論

謝謝,@Fan Cheung 談了很多關於如何組合多個 observable,總結一下你有兩種方法可以做到這一點

在此處輸入圖片說明

使用回調

 // componnet class myComponent { getMenu() { new sharedService().getMenu({ getFirstMenuList: () => { console.log('render first menu to template...') } }) } } // shared service class sharedService { getMenu(callback) { this.getFirstMenu$() .mergeMap(firstMenuList => { console.log('get first menu'); // if (callback.getFirstMenuList) { callback.getFirstMenuList(firstMenuList); } return Rx.Observable.from(firstMenuList); }) .mergeMap(firstMenu => this.getSecondMenu$(firstMenu.ID), (firstMenu, secondMenu) => { // console.log('get second menu'); // firstMenu.child = secondMenu return firstMenu; }) .reduce((acc, curr) => acc.concat(curr), []) .subscribe((menuList) => { console.log('all done'); }); } getFirstMenu$() { return Rx.Observable.of([{ ID: 'menu1', child: null }, { ID: 'menu2', child: null }, { ID: 'menu3', child: null }, ]); } getSecondMenu$(menuID) { let source = null; switch (menuID) { case 'menu1': source = [{ ID: 'subMenu1-1', }]; break; case 'menu2': source = [{ ID: 'subMenu2-1', }]; break; default: source = []; break; } const delayTime = ((Math.random() * 20) + 5) * 120; return Rx.Observable.of(source).delay(delayTime); } } // getTemplate new myComponent().getMenu();
 <script src="https://npmcdn.com/@reactivex/rxjs@5.0.0-beta.8/dist/global/Rx.umd.js"></script>

返回其他函數訂閱

 // componnet class myComponent { getMenu() { new sharedService().getMenu().subscribe(() => { console.log('render first menu to template...'); }) } } // shared service class sharedService { getMenu() { return this.getFirstMenu$() .mergeMap(firstMenuList => { console.log('get first menu'); return Rx.Observable.from(firstMenuList); }) .mergeMap(firstMenu => this.getSecondMenu$(firstMenu.ID), (firstMenu, secondMenu) => { // console.log('get second menu'); // firstMenu.child = secondMenu return firstMenu; }) .reduce((acc, curr) => acc.concat(curr), []) .do((menuList) => { console.log('all done'); }); } getFirstMenu$() { return Rx.Observable.of([{ ID: 'menu1', child: null }, { ID: 'menu2', child: null }, { ID: 'menu3', child: null }, ]); } getSecondMenu$(menuID) { let source = null; switch (menuID) { case 'menu1': source = [{ ID: 'subMenu1-1', }]; break; case 'menu2': source = [{ ID: 'subMenu2-1', }]; break; default: source = []; break; } const delayTime = ((Math.random() * 20) + 5) * 120; return Rx.Observable.of(source).delay(delayTime); } } // getTemplate new myComponent().getMenu();
 <script src="https://npmcdn.com/@reactivex/rxjs@5.0.0-beta.8/dist/global/Rx.umd.js"></script>

嘗試這個

getFirstMenu$()
.map(firstMenuList => Observable.from(firstMenuList))
.flatMap(firstMenu=> getSecondMenu$(firstMenu.ID))
.do(secondMenu => firstMenu.child = secondMenu)
.subcribe()

編輯1

getFirstMenu$()
.mergeMap(firstMenuList => Rx.Observable.from(firstMenuList))
.mergeMap(firstMenu=> getSecondMenu$(firstMenu.ID)
,(firstMenu, secondMenu) => {
 firstMenu.child=secondMenu
 return firstMenu
 })
.reduce((acc,curr)=>  acc.concat(curr) ,[])
.subscribe((menuList) => {
 console.log(menuList)
 });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM