RxJS:如何循环和处理多个http调用

RxJS:如何循环和处理多个http调用,rxjs,nestjs,Rxjs,Nestjs,我正在使用NestJS。我想从分页的API中获取所有数据(我不知道总页面)。现在我正在使用while循环获取所有数据,直到API返回204 No Content,这是到目前为止我的代码: async getProduct(){ 让productFinal:ProductItem[]=[]; let产品:ProductItem[]=[]; 设偏移量=1; let state=收集_state.InProgress; 让retryCount=1; 做{ const path=`product?lim

我正在使用NestJS。我想从分页的API中获取所有数据(我不知道总页面)。现在我正在使用while循环获取所有数据,直到API返回
204 No Content
,这是到目前为止我的代码:

async getProduct(){
让productFinal:ProductItem[]=[];
let产品:ProductItem[]=[];
设偏移量=1;
let state=收集_state.InProgress;
让retryCount=1;
做{
const path=`product?limit=50&offset=${offset}`;
产品=等待此.httpService
.get(路径,{headers,validateStatus:null})
.烟斗(
concatMap((响应)=>{
//如果状态代码为“204”,则循环完成
如果(response.status==204){
state=正在收集\u state.Finish;
}
//检查响应是否为错误
如果(response.status<200 | | response.status>=300){
//日志错误
记录器错误(
`[错误]在偏移量上收集产品时出错:${offset}。状态代码:${
答复.状态
}.Error:${JSON.stringify(response.data)}.Retrying…(${retryCount})`,
未定义,
“收集产品”
);
//增加retryCount
retryCount++;
//返回throwError以触发重试事件
返回throwError(`[ERROR]从HTTP调用收到状态${response.status});
}
//如果确定,则返回数据
返回(响应、数据、项目);
}),
catchError((err)=>{
如果(错误?.code){
//日志错误
记录器错误(
`连接错误:${err?.code}。正在重试…(${retryCount})`,
未定义,
“收集产品”
);
//增加retryCount
retryCount++;
}
回程抛掷器(err);
}),
//重试三次
重试(3),
//如果仍有错误,则停止循环
catchError((err)=>{
记录器错误(
`[错误]结束重试。错误:${err?.code??err}`,
未定义,
“收集产品”
);
state=正在收集\u state.Finish;
返回(err);
})
)
.toPromise();
//再次将retryCount设置为1
retryCount=1;
//检查是否定义了产品
如果(产品?长度>0){
//如果是,将产品推到最终变量
productFinal=联合(产品,productFinal);
}
//增加偏移量
offset++;
//并在状态未完成时循环
}while((状态为收集状态)!==收集状态.Finish);
返回产品最终版本;
}
端点
product?limit=50&offset=${offset}
来自第三方服务,它没有一个端点来获取所有数据,因此这是唯一的方法,它每个
offset
的最大
限制为50,而且它没有关于响应的
nextPage
totalPage
信息,因此我必须生成
offset
变量,并在上一个请求完成后将其递增

如何用RxJS操作符替换while循环?它是否可以优化为一次发出多个请求(可能四个或五个),从而减少获取所有数据的时间?

基于来自的答案,但每次发出请求时都会增加偏移量:

const{of,timer,defer,EMPTY,from,concat}=rxjs;//=要求(“rxjs”)
const{map,tap,mapTo,mergeMap,take}=rxjs.operators;//=要求(“rxjs/操作员”)
//模拟网络请求
函数fetchPage({limit,offset}){
//204响应
如果(偏移量>20){
返回({status:204,items:null});
}
//定期数据响应
返回计时器(100)。管道(
点击(()=>
log(`->从${offset}到${offset+limit}提取元素)
),
马普托({
现状:200,
项:数组.from({length:limit}).map((u,i)=>offset+i)
})
);
}
常数限值=10;
函数getItems(偏移量=0){
返回延迟(()=>fetchPage({limit,offset})).pipe(
合并映射({status,items})=>{
如果(状态===204){
返回空;
}
const items$=来自(个项目);
const next$=getItems(偏移量+限制);
返回concat(items$,next$);
})
);
}
//只处理前100个项目,不提取所有数据
getItems()
.管道(取(100))
.订阅({
下一步:console.log,
错误:console.error,
complete:()=>console.log(“complete”)
});

当您不需要分页时,为什么要使用分页?一次从端点抓取所有内容。分页来自API,不是我的。API没有提供一个端点来获取所有这些数据,然后给它一个上限值(比如max int值)。我想你没有明白我的意思,我上面的代码正在运行,我问我是否可以用rxjs操作符替换while循环。我想知道我是否可以优化它,一次发出多个请求,只发出一个呼叫,而不是100个,1k或10k呼叫才是优化。您的循环正在浪费您的资源-如果循环并行运行,这并不重要。