Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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
如何批量添加rxjs可观察对象返回的数组/列表?_Rxjs - Fatal编程技术网

如何批量添加rxjs可观察对象返回的数组/列表?

如何批量添加rxjs可观察对象返回的数组/列表?,rxjs,Rxjs,有一个可观察的返回数组/事物列表:可观察 我有一个用例,它是一个非常昂贵的事情,对于这个可观察的下游消费者来说,将更多的项目添加到这个列表中。因此,我想放慢添加到这个列表中的数量,但不要放松 类似于一个操作符,它获取这个可观察对象并返回另一个具有相同签名的可观察对象,但是每当一个新列表被推到它上面,并且它比上次有更多的项,那么一次只添加一个或几个 因此,如果上一次推送是一个包含3个项目的列表,下一次推送有3个额外的项目,总共包含6个项目,并且批量大小为1,那么这个列表推送将被拆分为3个单独的列表

有一个可观察的返回数组/事物列表:可观察

我有一个用例,它是一个非常昂贵的事情,对于这个可观察的下游消费者来说,将更多的项目添加到这个列表中。因此,我想放慢添加到这个列表中的数量,但不要放松

类似于一个操作符,它获取这个可观察对象并返回另一个具有相同签名的可观察对象,但是每当一个新列表被推到它上面,并且它比上次有更多的项,那么一次只添加一个或几个

因此,如果上一次推送是一个包含3个项目的列表,下一次推送有3个额外的项目,总共包含6个项目,并且批量大小为1,那么这个列表推送将被拆分为3个单独的列表推送,长度为:4、5、6


因此,添加内容是成批的,这样消费者就可以更容易地跟上列表中的新添加内容。或者,消费者不必每次在处理阵列/列表中的其他项目时都暂停这么长时间,因为添加的内容被拆分并分布在可配置的批次大小上。

我制作了一个addAdditionalOnIdle操作符,您可以使用管道操作符将其应用于任何可观察到的RxJ。它采用batchSize参数,因此您可以配置批次大小。它还需要一个dontBatchAfterThreshold,它在某个列表大小之后停止列表的批处理,这对我的目的很有用。结果还包含一个morePending值,当您知道有更多数据输入时,可以使用该值显示加载指示器

当浏览器中有空闲时间时,该实现在内部使用新的requestIdleCallback函数来安排额外项目的批量推送。这个函数在IE或Safari中还不可用,但我发现它有一个优秀的polyfill,所以你今天就可以使用它了:)

请参见下面的addAdditionalOnIdle的实现和示例用法:

const{NEVER,of,Observable}=rxjs;
const{concat}=rxjs.operators;
/**
*附加的
*
*仅适用于产生数组类型值的观察值。
*在window.requestIdleCallback上添加其他元素
*
*@param batchSize在每个空闲回调上添加的值量
*@param dontBatchAfterThreshold在返回的项目数量超过此阈值后返回所有项目
*/
函数addAdditionalOnIdle(
batchSize=1,
dontBatchAfterThreshold=22,
) {
返回(源)=>{
返回可观察的。创建((观察者)=>{
让idleCallback;
设currentPushedItems=[];
让lastItemsReceived=[];
让sourceSubscription=source
.订阅({
完成:()=>{
observer.complete();
},
错误:(错误)=>{
观察者错误(错误);
},
下一步:(项目)=>{
lastItemsReceived=项目;
if(idleCallback){
返回;
}
如果(lastItemsReceived.length>currentPushedItems.length){
常量idleCbFn=()=>{
如果(currentPushedItems.length>lastItemsReceived.length){
下一个({
莫雷:错,
值:lastItemsReceived,
});
idleCallback=未定义;
返回;
}
const to=currentPushedItems.length+batchSize;
const last=lastItemsReceived.length;
如果(currentPushedItems.length{
idleCbFn();
});
}否则{
idleCallback=未定义;
}
下一个({
morePending:currentPushedItems.length{
idleCbFn();
});
}否则{
currentPushedItems=收到的最后一项;
下一个({
莫雷:错,
值:currentPushedItems,
});
}
},
});
return()=>{
sourceSubscription.unsubscripte();
sourceSubscription=未定义;
lastItemsReceived=未定义;
currentPushedItems=未定义;
if(idleCallback){
window.cancelIdleCallback(idleCallback);
idleCallback=未定义;
}
};
});
};
}
函数睡眠(毫秒){
var start=new Date().getTime();
对于(变量i=0;i<1e7;i++){
如果((新日期().getTime()-start)>毫秒){
打破
}
}
}
让testSource=of(
[1,2,3],
[1,2,3,4,5,6],
).烟斗(
康卡特(从未)
);
测试源
.管道(添加附加管道(2))
.订阅((列表)=>{
//模拟具有繁忙循环睡眠实现的慢速同步使用者
睡眠(1000);
document.body.innerHTML+=“”+list.value+“

”; });
若要在服务器环境中使用此代码,则需要重构此代码,因为Windows在此类环境中不可用。