Node.js 如何等待stream.write()的循环结束
我正在使用节点的fs.WriteStream将数据写入文件。我在一个对象数组中循环,并使用write()函数写入每个对象 问题是,我想知道一旦这个循环结束,所有write()调用都完成了,但我无法让它工作 我尝试了一些解决方案,例如不使用流,但这会产生其他问题。我上次尝试的解决方案是在循环中检查它是否是最后一项,如果是,则关闭、结束或销毁流 这些都不起作用。该事件在文件实际写入之前发生 下面是我的代码,非常感谢您的帮助。多谢各位Node.js 如何等待stream.write()的循环结束,node.js,fs,node-streams,createwritestream,Node.js,Fs,Node Streams,Createwritestream,我正在使用节点的fs.WriteStream将数据写入文件。我在一个对象数组中循环,并使用write()函数写入每个对象 问题是,我想知道一旦这个循环结束,所有write()调用都完成了,但我无法让它工作 我尝试了一些解决方案,例如不使用流,但这会产生其他问题。我上次尝试的解决方案是在循环中检查它是否是最后一项,如果是,则关闭、结束或销毁流 这些都不起作用。该事件在文件实际写入之前发生 下面是我的代码,非常感谢您的帮助。多谢各位 async function writeFile(path
async function writeFile(path, data) {
try {
const writeStream = fs.createWriteStream(path, {
flags: "w"
})
data.forEach((file, index) => {
writeStream.write(`${file.name}\n`, (err) => {
if(err) throw err
if(index === (data.length - 1)) writeStream.end(); //I attempted close() and destroy() too, none worked
})
})
writeStream.on("finish", () => {
console.log("All files were written.") //Currently being emmited before all is written.
})
} catch (err) {
throw (err)
}
}
你能试试这个方法吗
const util = require("util");
async function writeFile(path, data) {
try {
const writeStream = fs.createWriteStream(path, {
flags: "w"
});
const promisify = util.promisify(writeStream.write);
for (const file of data) {
await promisify(`${file.name}\n`);
}
writeStream.end();
writeStream.on("finish", () => {
console.log("All files were written.");
});
} catch (error) {
console.log('error',error);
throw (error)'
}
}
由于您的文件数据已经在内存中,因此看起来并没有那么大,所以我只需在内存中对其进行转换,然后通过调用
fs.writeFile()
或fs.promises.writeFile()
将其写出
如果您真的想使用流,那么您必须非常小心地注意
.write()
在写入缓冲区满时返回的内容,以便您可以等待排出事件
const fs = require('fs');
function writeFile(path, data, completionCallback) {
let index = 0;
const writeStream = fs.createWriteStream(path, { flags: "w" });
writeStream.on('error', function(err) {
// stream will be automatically closed here
completionCallback(err);
});
// write one piece of data and call callback
// when ready to write the next piece of data
function writeData(data, cb) {
if (!writeStream.write(data)) {
// when .write() returns false, you have to wait for the drain
// event before doing any more writing
stream.once('drain', cb);
} else {
// so we always call the callback asynchronously and have no
// stack buildup
process.nextTick(cb);
}
}
function run() {
if (index < data.length) {
let line = data[index++].name + "\n";
writeData(line, run);
} else {
// all done with no errors
writeStream.end(completionCallback);
}
}
run();
}
const fs=require('fs');
函数writeFile(路径、数据、completionCallback){
设指数=0;
const writeStream=fs.createWriteStream(路径,{flags:“w”});
writeStream.on('error',函数(err){
//该流将在此处自动关闭
完成回调(err);
});
//写一段数据并调用callback
//准备好写入下一段数据时
函数writeData(数据,cb){
如果(!writeStream.write(数据)){
//当.write()返回false时,您必须等待排水
//事件,然后再继续编写
一次(“排水”,cb);
}否则{
//因此,我们总是异步调用回调,并且没有
//堆积
过程。nextTick(cb);
}
}
函数运行(){
if(索引<数据长度){
让line=data[index++].name+“\n”;
写入数据(行、运行);
}否则{
//一切都完成了,没有错误
writeStream.end(completionCallback);
}
}
run();
}
也许这有帮助?否则,将循环用于以下内容:const promisify=util.promisify(writeStream)代码>writeStream
是带有方法的对象,而不是函数。您不需要传递promisify()
单个函数吗?仍然存在一些问题stream.write()
返回一个布尔值,它告诉您流缓冲区是否已满,并且在写入更多缓冲区之前必须等待排水事件。这并不能解释这一点。此外,流错误不能可靠地通过.write()
回调来实现-它们是通过错误事件实现的。溪流的承诺非常混乱,因为它们的事件驱动系统根本不符合承诺。@pedrodalla-这回答了你的问题吗?如果是这样的话,您可以通过单击答案左侧的复选标记向社区表明这一点,这也将为您赢得一些遵守正确程序的声誉积分。
const fs = require('fs');
function writeFile(path, data, completionCallback) {
let index = 0;
const writeStream = fs.createWriteStream(path, { flags: "w" });
writeStream.on('error', function(err) {
// stream will be automatically closed here
completionCallback(err);
});
// write one piece of data and call callback
// when ready to write the next piece of data
function writeData(data, cb) {
if (!writeStream.write(data)) {
// when .write() returns false, you have to wait for the drain
// event before doing any more writing
stream.once('drain', cb);
} else {
// so we always call the callback asynchronously and have no
// stack buildup
process.nextTick(cb);
}
}
function run() {
if (index < data.length) {
let line = data[index++].name + "\n";
writeData(line, run);
} else {
// all done with no errors
writeStream.end(completionCallback);
}
}
run();
}