fs.appendFile()的文档在原子性保证方面是模糊的。
我特别想知道,如果在同一个文件上调用两个或多个数据,而不等待回调,那么数据是否可能被交错或删除(例如,由于对重叠区域的写入)。例如,以以下代码为例:
fs.writeFileSync('blort.bin', '');
for (let i = 0; i < 10; i++) {
const data = Buffer.alloc(65536, i);
fs.appendFile('blort.bin', data, () => {});
}假设没有文件系统错误,也没有其他写入文件的进程,那么在完成所有附加操作之后,Node会做出以下保证吗?
我也很好奇是否有任何序列化保证(尽管我假设没有)。也就是说,附件是否保证按顺序执行?
UPDATE:补充说明这是执行文件的唯一代码。
发布于 2017-06-09 18:44:22
据我所知,您的追加将按顺序进行,除非另一个进程正在写入目标文件,否则不会覆盖现有数据。
节点是单线程的(从运行中的应用程序的角度来看),并将文件内部写入队列,因此如果将1 2和3写入文件,文件将包含123。
节点确实会启动新线程来处理IO,但是这是运行时的一个特性,并且对开发人员是隐藏的。
更新
在第一次阅读时,我忽略了您的要求,即在回调为空白或非功能性的多个调用中会出现追加。
这极大地改变了事情。
如果使用异步调用(如fs.appendFile() ),则必须提供一个回调,该回调必须检查错误。如果您堆栈异步调用而不等待它们的回调结束,则无法保证您的写入将按顺序进行或不会覆盖以前的数据。
底线:如果没有正确的回调,不会使用异步函数,这些回调总是检查错误。
否则,就会打破Node事件驱动模型的整个概念。
我通常解释这一点的方式是考虑到,在异步调用中,由于cpu和IO负载等多种因素,无法预测何时会触发回调。
如果无法知道何时触发回调,则无法预测多个调用将按顺序运行。
更新2
为了明确起见,如果不提供回调并保证没有任何预期的行为,就不能调用异步函数。
从事件的角度想一想:
fs.appendFile()向IO线程添加事件处理程序,并向IO线程发送包含其参数的事件。
操作完成后,将触发此事件处理程序,该事件处理程序要么是您的回调,要么将触发您的回调。
如果不等待操作完成,您就无法保证它已经成功或完成了您所期望的操作。
https://stackoverflow.com/questions/44464284
复制相似问题