我每次都有一个可观察到的从流中获取数据,大小分别为512,我必须将其分解为其他可观察到的200个字符,并将[12] char保留在其他缓冲区中以与下一个块连接,我使用新主题和for循环,我相信可能会有更好,更漂亮的解决方案。
可观察到的----------------------------------------
第n次迭代[512] [194]-> [106] [200] [200] [106 + 94]-> [200] [200] [200]
第n + 1个[512] [6] .......
maxValueSize = 200
this._sreamRecord$.subscribe(
{
next: (val) => {
const bufferToSend: Buffer = Buffer.concat([completationBuffer, val])
for (let i = 0; i < bufferToSend.length; i += maxValueSize) {
if (bufferToSend.length - i > maxValueSize) {
bufferStreamer.next(bufferToSend.slice(i, i + maxValueSize))
} else {
completationBuffer = bufferToSend.slice(i, i + maxValueSize)
}
}
},
complete() {
if (completationBuffer.length) {
bufferStreamer.next(completationBuffer)
}
bufferStreamer.complete()
}
})
答案 0 :(得分:0)
您可能需要考虑以下解决方案
const splitInChunksWithRemainder = (remainder: Array<any>) => {
return (streamRecord: Array<any>) => {
const streamRecordWithRemainder = remainder.concat(streamRecord);
let chunks = _.chunk(streamRecordWithRemainder, maxValueSize);
const last = chunks[chunks.length - 1];
let newRemainder = [];
if (last.length != maxValueSize) {
newRemainder = chunks[chunks.length - 1];
chunks.length = chunks.length - 1;
}
return {chunks, newRemainder};
};
}
let f = splitInChunksWithRemainder([]);
this._sreamRecord$.pipe(
switchMap(s => {
const res = f(s);
f = splitInChunksWithRemainder(res.newRemainder);
return from(res.chunks);
})
)
.subscribe(console.log);
这个想法是在连接上一个 remainder 后,用streamRecord
lodash
函数分割每个chunk
,即从前一个streamRecord
。
这是通过函数splitInChunksWithRemainder
完成的,该函数是更高级别的函数,即在返回remainder
的情况下返回函数的函数来自上一个拆分。
评论后更新
如果您还需要发出 last newRemainder
,则可以考虑以下更复杂的解决方案
const splitInChunksWithRemainder = (remainder: Array<any>) => {
return (streamRecord: Array<any>) => {
const streamRecordWithRemainder = remainder.concat(streamRecord);
let chunks = _.chunk(streamRecordWithRemainder, maxValueSize);
const last = chunks[chunks.length - 1];
let newRemainder = [];
if (last.length != maxValueSize) {
newRemainder = chunks[chunks.length - 1];
chunks.length = chunks.length - 1;
}
return {chunks, newRemainder};
};
}
const pipeableChain = () => (source: Observable<any>) => {
let f = splitInChunksWithRemainder([]);
let lastRemainder: any[];
return source.pipe(
switchMap(s => {
const res = f(s);
lastRemainder = res.newRemainder;
f = splitInChunksWithRemainder(lastRemainder);
return from(res.chunks);
}),
concat(defer(() => of(lastRemainder)))
)
}
_streamRecord$.pipe(
pipeableChain()
)
.subscribe(console.log);
我们引入了pipeableChain
函数。在此函数中,我们保存通过执行splitInChunksWithRemainder
返回的余数。源Observable完成后,我们将通过concat
运算符添加最后一个通知。
如您所见,我们还必须使用defer
运算符来确保仅在观察者订阅时(即在源Observable完成之后)创建Observable。如果没有defer
,则在最初订阅源Observable时(即,当concat
仍未定义时)将创建作为参数传递给lastRemainder
的Observable。