Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/408.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 通过文件缓冲_Javascript_Node.js_Stream_Highland.js - Fatal编程技术网

Javascript 通过文件缓冲

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)

我有一个场景,在这个场景中,我的生产商比拥有大量数据的消费者运行得快得多。但是,我不想阻止制作人。因此,唯一的选择是通过文件缓冲额外的数据

我已经设法找到了一个非最优的解决方案。然而,必须有一种更加务实的方式来实现这一点

我更熟悉RxJS,在那里我可能不会有太多问题,但我刚刚开始转向高地,希望得到一些建议

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在源代码上非常懒惰,因此当接收器以自己的速度工作时,让这个中间贪婪文件缓冲源代码并不容易。请注意,由于背压,本机节点流也会出现同样的问题。高地可能有更好的方法,但我现在看不到。主要的问题是如何从仍在编写的文件中读取。自定义双工流可能会抽象出这一点。做了一些接近,但我不认为它是贪婪的来源。