我有一个REST端点,它返回一个项目列表,一次最多1000个项目.如果有超过1000个项目,则响应具有HTTP状态206,并且我可以在下一个获取更多项目的请求中使用Next-Range标头.
我正在研究一个Angular 2应用程序并试图用Http和Observable实现它.我的问题是我不知道如何合并多个Observable,具体取决于有多少个页面,最后返回一个我的组件可以订阅的Observable.
这是我使用当前TypeScript实现的地方:
// NOTE: Non-working example! getAllItems(): Observable<any[]> { // array of all items,possibly received with multiple requests const allItems: any[] = []; // inner function for getting a range of items const getRange = (range?: string) => { const headers: Headers = new Headers(); if (range) { headers.set('Range',range); } return this.http.get('http://api/endpoint',{ headers }) .map((res: Response) => { // add all to received items // (maybe not needed if the responses can be merged some other way?) allItems.push.apply(allItems,res.json()); // partial content if (res.status === 206) { const nextRange = res.headers.get('Next-Range'); // get next range of items return getRange(nextRange); } return allItems; }); }; // get first range return getRange(); }
但是,这不起作用.如果我理解正确,则返回Observable作为初始Observable的值而不是项数组.
您可以使用expand运算符实现此功能.你真正想要做的是创建一个递归的flatmap.这正是操作符扩展的目的.
原文链接:https://www.f2er.com/angularjs/143454.html以下是其工作原理的代码段:
let times = true; // This is a mock method for your http.get call const httpMock = () => { if(times) { times = false; return Rx.Observable.of({items: ["1","2","3"],next: true}); } else { return Rx.Observable.of({items: ["4","5","6"],next: false}); } } httpMock() .expand(obj => { // In your case,the obj will be the response // implement your logic here if the 206 http header is found if(obj.next) { // If you have next values,just call the http.get method again // In my example it's the httpMock return httpMock(); } else { return Rx.Observable.empty(); } }) .map(obj => obj.items.flatMap(array => array)) .reduce((acc,x) => acc.concat(x),[]); .subscribe((val) => console.log(val));
我们做的是模拟第一个http请求,它具有true的’next’属性.这符合您的206标头.然后我们进行第二次调用,其中’next’属性为false.
结果是一个包含两个请求的结果的数组.由于扩展运算符,它也适用于更多请求.
工作jsbin示例可以在这里找到:http://jsbin.com/wowituluqu/edit?js,console
编辑:更新以使用从数组返回数组的http调用,最终结果是包含数组中所有元素的单个数组.
如果您希望结果中包含来自请求的单独数组的数组,只需删除flatmap并直接返回项目.在这里更新codepen:
http://codepen.io/anon/pen/xRZyaZ?editors=0010#0