我正在使用 rxjs v6.4.0。我正在尝试通过 API 进行分页,搜索名称等于“开发”的非常具体的 channel 。我正在使用 expand
递归调用 API 并获取新页面。最终结果为我提供了一个串联的 channel 列表。然后我过滤掉名称不等于“开发”的所有 channel 。但是我收到一个错误:TypeError:您在需要流的位置提供了“未定义”。您可以提供 Observable、Promise、Array 或 Iterable。
const Rx = require('rxjs')
const Rx2 = require('rxjs/operators')
const getChannel = (cursor) => {
return this.service.getData(`${url}?cursor=${cursor || ''}`)
.pipe(Rx2.map(resp => JSON.parse(resp.body)))
.pipe(Rx2.expand(body => { // recurse the api until no more cursors
return body.response_metadata &&
body.response_metadata.next_cursor ?
getChannel(body.response_metadata.next_cursor) : Rx.EMPTY
}))
.pipe(Rx2.pluck('channels'))
.pipe(Rx2.mergeAll()) // flattens array
.pipe(Rx2.filter(c => {
console.log('finding', c.name === 'development')
return c.name === 'development'
}))
}
最佳答案
find
回调应该返回一个 bool 值,而不是一个 Observable。例如
find(c => c.name === 'development')
更新
这是您的修改示例。我删除了生成器,因为它们比我们的案例需要的更复杂。
const { of, EMPTY, throwError } = rxjs;
const { filter, tap, expand, pluck, mergeAll } = rxjs.operators;
const DATA =
[ {channels: [{id: 123, name: 'test'}, {id:4, name: 'hello'}], cursor: 1}
, {channels:[{id: 1, name: 'world'}, {id: 2, name: 'knows'}], cursor: 2}
, {channels:[{id: 3, name: 'react'}, {id: 5, name: 'devcap'}], cursor: false}
];
function getChannel(){
return getBlock()
.pipe(
expand(x => x.cursor ? getBlock(x.cursor) : EMPTY),
pluck('channels'),
mergeAll(),
filter(c => c.name === 'devcap')
)
}
getChannel().subscribe({
next: console.log,
error: console.error
});
function getBlock(index = 0) {
if (index >= DATA.length){
throwError('Out of bounds');
}
return of(DATA[index]);
}
更新 2
由于仅通过 getChannel()
完成递归,您的解决方案无效。当您执行 expand
时——您通过 getChannel()
运行另一个循环。这意味着您对每个递归获取的值运行 pluck-mergeAll-filter
chain 两次!采摘和奉承它两次给你 undefined
—— 因此错误。
在你的 playground 中——尝试分离出这段代码
let getValue = ()=>{
const next = gen.next();
if (!next || !next.value) { return EMPTY; }
return next.value;
}
并在扩展中使用它,像这样:
let getChannel = () => {
return getValue()
.pipe(
expand(body => {
return body.cursor ? getValue() : EMPTY
}),
pluck('channels'),
mergeAll(),
filter(c => c.name === 'devcap'),
)
}
关于javascript - RxJs:通过 API 递归分页并从列表中查找值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55274246/