Javascript 用于将块写入文件的事件驱动模式-JS
我试图通过WebRTC传输一个文件,我正在努力找出一个好的模式来写入数据。因为文件块将以未知的速率进入,所以我需要能够在每个块可用时编写它;这意味着两件事: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
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)的顺序并不重要。对。说得好。今晚我会实施,我会让你知道进展如何。