我很困惑使用管道来处理写入流是同步还是不同步,因为我发现了一个关于callback to handle completion of pipe的问题
我只是想确保写入流在完成其他人之前完成fs.rename
,所以我宣传它,代码如下:
(async function () {
await promiseTempStream({oldPath, makeRegex, replaceFn, replaceObj, tempPath})
await rename(tempPath, oldPath)
function promiseTempStream({oldPath, makeRegex, replaceFn, replaceObj, tempPath}) {
return new Promise((res, rej) => {
const writable = fs.createWriteStream(tempPath)
fs.createReadStream(oldPath, 'utf8')
.pipe(replaceStream(makeRegex ,replaceFn.bind(this, replaceObj), {maxMatchLen: 5000}))
.pipe(writable)
writable
.on('error', (err) => {rej(err)})
.on('finish', res)
})
}
}())
它有效,但在阅读pipe doc之后我感到困惑,因为它说
默认情况下,当源可读流发出'end'时,在目标可写流上调用stream.end(),以便目标不再可写。
所以我只需要
await fs.createReadStream(oldPath, 'utf8')
.pipe(replaceStream(makeRegex ,replaceFn.bind(this, replaceObj), {maxMatchLen: 5000}))
.pipe(fs.createWriteStream(tempPath))
await rename(tempPath, oldPath)
或只是
fs.createReadStream(oldPath, 'utf8')
.pipe(replaceStream(makeRegex ,replaceFn.bind(this, replaceObj), {maxMatchLen: 5000}))
.pipe(fs.createWriteStream(tempPath))
await rename(tempPath, oldPath)
这是正确的方法吗?非常感谢你
答案 0 :(得分:4)
您需要等待tempPath流上的finish
事件。所以你可以做类似
async function createTheFile() {
return new Promise<void>(resolve => {
let a = replaceStream(makeRegex, replaceFn.bind(this, replaceObj), { maxMatchLen: 5000 });
let b = fs.createWriteStream(tempPath);
fs.createReadStream(oldPath, 'utf8').pipe(a).pipe(b);
b.on('finish', resolve);
}
}
await createTheFile();
rename(tempPath, oldPath);
基本上我们在这里创建了一个promise,当我们完成写入tempFile时解析。在继续前进之前,你需要等待这个承诺。
中提到的流中添加一些错误处理代码,那将会很棒。