Javascript 通过文件缓冲
我有一个场景,在这个场景中,我的生产商比拥有大量数据的消费者运行得快得多。但是,我不想阻止制作人。因此,唯一的选择是通过文件缓冲额外的数据 我已经设法找到了一个非最优的解决方案。然而,必须有一种更加务实的方式来实现这一点 我更熟悉RxJS,在那里我可能不会有太多问题,但我刚刚开始转向高地,希望得到一些建议Javascript 通过文件缓冲,javascript,node.js,stream,highland.js,Javascript,Node.js,Stream,Highland.js,我有一个场景,在这个场景中,我的生产商比拥有大量数据的消费者运行得快得多。但是,我不想阻止制作人。因此,唯一的选择是通过文件缓冲额外的数据 我已经设法找到了一个非最优的解决方案。然而,必须有一种更加务实的方式来实现这一点 我更熟悉RxJS,在那里我可能不会有太多问题,但我刚刚开始转向高地,希望得到一些建议 import fs from 'fs-promise' import _ from 'highland' export default function buffer(id, source)
import fs from 'fs-promise'
import _ from 'highland'
export default function buffer(id, source) {
const ctx = {
fd: null,
written: 0,
read: 0,
eof: false,
err: null,
path: `/tmp/${id}`
}
async function drain(push) {
ctx.fd = ctx.fd || await fs.open(ctx.path, 'w+')
const bufferSize = 1024 * 1024
while (ctx.read < ctx.written) {
let buffer = new Buffer(bufferSize)
buffer = buffer.slice(0,
await fs.read(ctx.fd, buffer, 0, buffer.length, ctx.read))
if (buffer.length === 0) {
break
}
ctx.read += buffer.length
push(null, buffer)
}
}
// TODO: What about errors?
source.each(async (x) => {
try {
ctx.fd = ctx.fd || await fs.open(ctx.path, 'w+')
if (x === _.nil) {
ctx.eof = true
} else {
ctx.written += await fs.write(ctx.fd, x, 0, x.length, ctx.written)
}
} catch (err2) {
ctx.err = err2
}
})
return _(async (push, next) => {
try {
await drain()
if (ctx.err) {
throw ctx.err
} else if (ctx.eof) {
await drain()
fs.unlink(ctx.path)
push(null, _.nil)
} else {
setTimeout(next, 40)
}
} catch (err2) {
fs.unlink(ctx.path)
push(err2)
}
})
}
从“fs承诺”导入fs
从“高地”导入
导出默认函数缓冲区(id,源){
常数ctx={
fd:null,
书面:0,
改为:0,
eof:错,
错误:空,
路径:`/tmp/${id}`
}
异步函数漏(推送){
ctx.fd=ctx.fd | |等待fs.open(ctx.path,“w+”)
常量缓冲大小=1024*1024
while(ctx.read{
试一试{
ctx.fd=ctx.fd | |等待fs.open(ctx.path,“w+”)
如果(x====0.nil){
ctx.eof=真
}否则{
ctx.writed+=等待fs.write(ctx.fd,x,0,x.length,ctx.writed)
}
}捕获(错误2){
ctx.err=err2
}
})
返回(异步(推送,下一步)=>{
试一试{
等待排水管
如果(ctx.err){
抛出ctx.err
}否则如果(ctx.eof){
等待排水管
fs.unlink(ctx.path)
推送(空,无)
}否则{
设置超时(下一步,40)
}
}捕获(错误2){
fs.unlink(ctx.path)
推送(错误2)
}
})
}
您在示例中使用了什么语言/解决方案来获得async/await构造?我使用babeljs实现async/await。默认情况下,highland在源代码上非常懒惰,因此当接收器以自己的速度工作时,让这个中间贪婪文件缓冲源代码并不容易。请注意,由于背压,本机节点流也会出现同样的问题。高地可能有更好的方法,但我现在看不到。主要的问题是如何从仍在编写的文件中读取。自定义双工流可能会抽象出这一点。做了一些接近,但我不认为它是贪婪的来源。