gpt4 book ai didi

javascript - RxJs:通过 API 递归分页并从列表中查找值

转载 作者:行者123 更新时间:2023-11-30 14:06:32 25 4
gpt4 key购买 nike

我正在使用 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com