Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript RxJs:通过API递归分页并从列表中查找值_Javascript_Rxjs_Operators_Expand_Pagination - Fatal编程技术网

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

Javascript RxJs:通过API递归分页并从列表中查找值,javascript,rxjs,operators,expand,pagination,Javascript,Rxjs,Operators,Expand,Pagination,我使用的是RXJSV6.4.0。我试图通过一个API分页,搜索一个非常特定的通道,其中的名称等于“development”。我使用expand递归调用API并获取新页面。最终结果为我提供了通道的串联列表。然后我过滤掉所有名称不等于“开发”的通道。然而,我得到了一个错误:TypeError:您在需要流的地方提供了“undefined”。您可以提供一个可观察的、承诺的、数组的或可观察的。 const Rx = require('rxjs') const Rx2 = require('rxjs/ope

我使用的是RXJSV6.4.0。我试图通过一个API分页,搜索一个非常特定的通道,其中的名称等于“development”。我使用
expand
递归调用API并获取新页面。最终结果为我提供了通道的串联列表。然后我过滤掉所有名称不等于“开发”的通道。然而,我得到了一个错误:
TypeError:您在需要流的地方提供了“undefined”。您可以提供一个可观察的、承诺的、数组的或可观察的。

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
回调应返回布尔值,而不是可观察值。例如

find(c=>c.name==='development')
更新

这是你的一个修改过的例子。我已经移除了发电机,因为它们比我们的案子需要的更复杂

const{of,EMPTY,throwError}=rxjs;
const{filter,tap,expand,pull,mergeAll}=rxjs.operators;
常数数据=
[{channels:[{id:123,name:'test'},{id:4,name:'hello'}],游标:1}
,{channels:[{id:1,name:'world'},{id:2,name:'knows'}],游标:2}
,{channels:[{id:3,名称:'react'},{id:5,名称:'devcap'}],游标:false}
];
函数getChannel(){
返回getBlock()
.烟斗(
展开(x=>x.cursor?getBlock(x.cursor):空),
弹拨(“通道”),
mergeAll(),
过滤器(c=>c.name=='devcap')
)
}
getChannel()。订阅({
下一步:console.log,
错误:console.error
});
函数getBlock(索引=0){
如果(索引>=DATA.length){
投掷者(“出界”);
}
返回(数据[索引]);
}
更新2

由于仅通过
getChannel()
执行递归,您的解决方案无法工作。当您执行
展开时
——通过
getChannel()
运行另一个循环。这意味着您对每个递归获取的值运行两次
pull mergeAll filter
chain!两次拨弄和奉承它会给你
未定义的
——因此是错误的

在你的操场上——试着把这个代码分开

让getValue=()=>{
const next=gen.next();
如果(!next | |!next.value){返回空;}
返回next.value;
}
并在展开中使用它,如下所示:

让getChannel=()=>{
返回getValue()
.烟斗(
展开(正文=>{
return body.cursor?getValue():空
}),
弹拨(“通道”),
mergeAll(),
过滤器(c=>c.name=='devcap'),
)
}

请告诉我这是否是您正在寻找的功能


我已更改为布尔值,并将
find
更改为
filter
。我得到了一个错误:您提供了一个“未定义”的预期流。您可以提供一个可观察的、承诺的、数组的或可观察的。@courtyen,很难说,不过这个错误似乎来自
expand()
。当您完成递归时--尝试返回,而不是
未定义的
我在我的
扩展中使用三元值更新了您的注释。不幸的是,我仍然收到与上面相同的错误。从日志中,我看到在我点击最后一个光标之前发出了错误。感谢Kos对此的帮助。给我一些时间,我会提供一个游乐场。我没有编辑答案来回应。我编辑它是因为我和他一起工作,虽然他解决了问题,但他没有完全清楚地回答问题。
const {
  of,
  EMPTY
} = rxjs;

const {
  filter,
  tap,
  expand,
  take,
  pluck,
  concatAll,
  flatMap,
  first
} = rxjs.operators;

function* apiResponses() {
  yield of({channels: [{id: 123, name: 'test'}, {id:4, name: 'hello'}], cursor: 1});
  yield of({channels:[{id: 3, name: 'react'}, {id: 5, name: 'devcap'}], cursor:3});
  yield of({channels:[{id: 1, name: 'world'}, {id: 2, name: 'knows'}], cursor: 2});
  yield of({channels:[{id: 4, name: 'react'}, {id: 6, name: 'devcap'}], cursor:4});
}

let gen = apiResponses();

function getChannel() {
  return gen.next().value // simulate api call
    .pipe(
      expand(body => {
        return body.cursor ? gen.next().value : EMPTY
      }),
      pluck('channels'),
      flatMap(channels => {
        const filtered = channels.filter(channel => channel.name === 'devcap')
        if(filtered.length) {
          return filtered;
        }
        return EMPTY;
      }),
    first()
    );
}


getChannel().subscribe(data => {
  console.log('DATA!! ', data)
  }, e => {
  console.log('ERROR', e)
  throw e
})