假设我们有这样一个程序:
// imagine the string1 to string1000 are very long strings,which will take a while to be written to file system var arr = ["string1",...,"string1000"]; for (let i = 1; i < 1000; i++) { fs.write("./same/path/file.txt",arr[i],{flag: "a"}}); }
我的问题是,string1到string1000是否会被保证按顺序附加到同一个文件?
由于fs.write是异步函数,我不确定每次调用fs.write()是如何执行的.我假设每个字符串的函数调用应放在另一个线程(如callstack?)中,并且一旦完成上一个调用,就可以执行下一个调用.
我不确定我的理解是否准确.
编辑1
在评论和答案中,我看到fs.write对于多次写入同一文件而不等待回调是不安全的.但是writestream怎么样?
如果我使用以下代码,它会保证写作顺序吗?
// imagine the string1 to string1000 are very long strings,"string1000"]; var fileStream = fs.createWriteFileStream("./same/path/file.txt",{ "flags": "a+" }); for (let i = 1; i < 1000; i++) { fileStream.write(arr[i]); } fileStream.on("error",() => {// do something}); fileStream.on("finish",() => {// do something}); fileStream.end();
任何评论或更正都会有所帮助!谢谢!
解决方法
docs说
Note that it is unsafe to use
fs.write
multiple times on the same file without waiting for the callback. For this scenario,fs.createWriteStream is strongly recommended.
使用流是有效的,因为流固有地保证写入它们的字符串的顺序与从它们读出的顺序相同.
var stream = fs.createWriteStream("./same/path/file.txt"); stream.on('error',console.error); arr.forEach((str) => { stream.write(str + '\n'); }); stream.end();
仍然使用fs.write但确保按顺序发生事情的另一种方法是使用promises来维护顺序逻辑.
function writeToFilePromise(str) { return new Promise((resolve,reject) => { fs.write("./same/path/file.txt",str,{flag: "a"}},(err) => { if (err) return reject(err); resolve(); }); }); } // for every string,// write it to the file,// then write the next one once that one is finished and so on arr.reduce((chain,str) => { return chain .then(() => writeToFilePromise(str)); },Promise.resolve());