Rx.js:从promise列表中获取所有结果作为数组

时间:2016-09-22 05:51:50

标签: javascript rxjs5

这是演示:



var availableNews$ = Rx.Observable.fromPromise(fetch('https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty').then(res => res.json()));
var pager$ = new Rx.Subject();
var fetchedNews$ = Rx.Observable.combineLatest(availableNews$, pager$, (news, pager) => news.slice((pager.current - 1) * pager.items_per_page, pager.items_per_page))
    .flatMap(id => id)
    .map(id => Rx.Observable.fromPromise(fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty`).then(res => res.json()))
    .concatMap(res => res));
pager$.subscribe(v => {
  console.log(v);
  document.querySelector('#pager').textContent = JSON.stringify(v);
});
fetchedNews$.subscribe(x => { 
  console.log(x);
  document.querySelector('#news').textContent = JSON.stringify(x);;
})
pager$.next({current: 1, items_per_page: 10})

<script src="https://unpkg.com/@reactivex/rxjs/dist/global/Rx.js"></script>
pager: <p id="pager"></p>
news: <p id="news"></p>
<p>the news return obserable instance instead of <em>array of fetched news</em> which is desired</p>
&#13;
&#13;
&#13;

我在代码中做这些事情:

1,获取热门新闻Feed(availableNews $)

2,使用寻呼机来限制应该获取哪些Feed(寻呼机$)

3,获取应该是数组的新闻(fetchedNews $)

但我在第3步发现,返回的结果是每个promiseObserable的流,而不是每个promise作为数组的结果。

感谢您的帮助^ _ ^

- 编辑 -

对于github上的rxjs,我问这个问题是issue,并得到一个更好的解决方案。这是代码:

const { Observable } = Rx;
const { ajax: { getJSON }} = Observable;

var availableNews$ = getJSON('https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty');
var pager$ = new Rx.Subject();
var fetchedNews$ = Observable
  .combineLatest(availableNews$, pager$, (news, {current, items_per_page}) => {
    return news.slice((current - 1) * items_per_page, items_per_page);
  })
  .switchMap((ids) => Observable.forkJoin(ids.map((id) => {
    return getJSON(`https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty`);
  })));

pager$.subscribe(v => {
  document.querySelector('#pager').textContent = JSON.stringify(v);
});

fetchedNews$.subscribe(stories => {
   document.querySelector('#news').textContent = JSON.stringify(stories);  
});

pager$.next({current: 1, items_per_page: 10})

1 个答案:

答案 0 :(得分:1)

您有两个或三个错误的组合。

首先,combineLatest()中的lambda不对新闻ID数组进行操作,而是对包含数组的单个项目进行操作。因此flatmap()concatMap()一样不需要Observable

其次,您无需从fetch()创建combineLatest(),如

第三,你所拥有的Observable没有提供在加载新闻时满载的Promise,但是当加载了availableNews和pager时。因此,您必须使用combineLatest()制作第三个fetch(),但必须使用subscribe() Promises数组。然后在第二个var availableNews$ = Rx.Observable.fromPromise(fetch('https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty').then(res => res.json())); var pager$ = new Rx.Subject(); var fetchedNews$ = Rx.Observable.combineLatest(availableNews$, pager$, (news, pager) => Rx.Observable.combineLatest.apply(this, news.slice((pager.current - 1) * pager.items_per_page, pager.items_per_page) .map(id => fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty`).then(res => res.json())))); pager$.subscribe(v => { document.querySelector('#pager').textContent = JSON.stringify(v); }); fetchedNews$.subscribe(x => { x.subscribe(a => { document.querySelector('#news').textContent = JSON.stringify(a); }); }) pager$.next({current: 1, items_per_page: 10})订阅,如下所示:

<script src="https://unpkg.com/@reactivex/rxjs/dist/global/Rx.js"></script>
pager: <p id="pager"></p>
news: <p id="news"></p>
<p>the news return obserable instance instead of <em>array of fetched news</em> which is desired</p>
{{1}}