Javascript 用于将块写入文件的事件驱动模式-JS

Javascript 用于将块写入文件的事件驱动模式-JS,javascript,design-patterns,file-io,webrtc,event-driven-design,Javascript,Design Patterns,File Io,Webrtc,Event Driven Design,我试图通过WebRTC传输一个文件,我正在努力找出一个好的模式来写入数据。因为文件块将以未知的速率进入,所以我需要能够在每个块可用时编写它;这意味着两件事: 如果数据输入速度过快,那么我们需要在当前写入任务完成后将每个块排队等待稍后写入 如果数据输入太慢,那么我们需要等待数据块变得可用 理想情况下,我希望避免依赖setTimeout()等待块到达。到目前为止,我所拥有的很接近,但并不完全是我想要的: // container to hold chunks as they come in var

我试图通过WebRTC传输一个文件,我正在努力找出一个好的模式来写入数据。因为文件块将以未知的速率进入,所以我需要能够在每个块可用时编写它;这意味着两件事:

  • 如果数据输入速度过快,那么我们需要在当前写入任务完成后将每个块排队等待稍后写入
  • 如果数据输入太慢,那么我们需要等待数据块变得可用
  • 理想情况下,我希望避免依赖
    setTimeout()
    等待块到达。到目前为止,我所拥有的很接近,但并不完全是我想要的:

    // container to hold chunks as they come in
    var chunkCollection = {};
    
    // callback function for RTCDataChannel messages
    function onData(data) {
    
      chunkCollection[data.chunkIndex] = data.chunk;
      writeToFile(data.chunkIndex);
    }
    
    function writeToFile(chunkIndexToWrite) {
    
      // if we have the next chunk, write it to the file
      if (chunkCollection[chunkIndexToWrite]) {
        var chunk = chunkCollection[chunkIndexToWrite];
        delete chunkCollection[chunkIndexToWrite];
        fileWriter.seek(chunk.offset);
        fileWriter.write(chunk.blob);
      }
      else {
        // we don't have the next chunk, so we have to wait
        setTimeout(function() {
          writeToFile(chunkIndexToWrite);
        }, 100);
      }
    }
    
    这样做的问题是,如果块进入得太快,
    fileWriter
    将无法编写下一个块,并将抛出异常。然而,如果块进入太慢,设置正确的超时将非常棘手

    似乎事件驱动的方法在这里最有效。一个事件是来自
    RTCDataChannel
    的数据消息。另一个事件是
    fileWriter
    已完成写入,并准备写入下一个块。但我一直坚持的一点是如何正确地等待一大块肉进来

    如果浏览器不忙着写入文件,而只是坐在那里等待数据块进入,那么浏览器应该在数据块可用时立即开始写入数据块。但是如果没有一个丑陋的
    setTimeout
    循环,我就不知道如何做到这一点;我不知道如何发布一个事件,说我们不需要再等待了,可以继续写作


    这样做的好模式是什么?

    有一种方法可以在不超时的情况下完成,尽管它使用标志指示writer可用,但它仍然应该比timeout循环更好

    我将创建一个队列,当数据块到达时将在其中存储数据块,并使用异步fileWriter(在完成对文件的写入时进行回调的文件编写器)

    就像这样:

    
    var readyToWrite = true;
    var chunks = [];
    
    var onData = function(data) {
        chunks.push(data);
        if (readyToWrite) {
             writeChunksToFile(chunks);
        }
    };
    
    var writeChunksToFile = function() {
        if (chunks) {
            readyToWrite = false;
            fileWriter.write(chunks.shift(), function() {
                writeChunksToFile(chunks);
            });
        } else {
            readyToWrite = true;
        }
    };
    
    通过这种方式,writer一直在写,直到块变为空,然后它通知数据接收方(使用标志)它可用,所以数据接收方(onData)知道它必须在接收到下一个块时再次调用它。若数据接收方得到数据,而writer仍在向文件写入数据,那个么它不会调用它,它只会将数据块推送到我们的队列数组,而writer在完成写入时会得到该数据块,因为它是递归调用的


    这是我们可以用这种方法编写的最简单的代码,但您可以使用observer模式使其“更面向对象”,或使用Monad使其“更具功能”。

    有趣。。。我有一种感觉,这里有一个比赛条件,但我会尝试正确地实现这一点,看看它的表现如何。谢谢不应该存在争用条件,因为js是单线程异步的。事件循环中事件(onData和fileWriteEnded)的顺序并不重要。对。说得好。今晚我会实施,我会让你知道进展如何。