Node.js 如何创建文件流并异步写入流?

Node.js 如何创建文件流并异步写入流?,node.js,typescript,file,promise,Node.js,Typescript,File,Promise,我不熟悉TypeScript/JavaScript和Node。 现在,我正在尝试创建一个文件流,并将“Hello!”异步写入该流 #!/usr/bin/env node import fs from 'fs'; function createStream(filePath: string): Promise<fs.WriteStream> { return new Promise<fs.WriteStream>((resolve, reject) => {

我不熟悉TypeScript/JavaScript和Node。
现在,我正在尝试创建一个文件流,并将“Hello!”异步写入该流

#!/usr/bin/env node

import fs from 'fs';

function createStream(filePath: string): Promise<fs.WriteStream> {

  return new Promise<fs.WriteStream>((resolve, reject) => {

    const out = fs.createWriteStream(filePath);

    out.on('close', () => {
      console.log(filePath + ' closed');
      resolve(out);
    });

    out.on('error', (err: any) => {
      console.log(filePath + ' ' + err);
      reject(err);
    });

  });
}

createStream('/tmp/test.txt').then((out:fs.WriteStream) => {
  console.log(out);
  out.write('Hello!');
  out.end();
}) 
#/usr/bin/env节点
从“fs”导入fs;
函数createStream(文件路径:字符串):Promise{
返回新承诺((解决、拒绝)=>{
const out=fs.createWriteStream(文件路径);
out.on('关闭',()=>{
log(filePath+‘closed’);
解决;
});
out.on('error',(err:any)=>{
日志(文件路径+“”+错误);
拒绝(错误);
});
});
}
createStream('/tmp/test.txt')。然后((out:fs.WriteStream)=>{
控制台。注销;
出去。写(‘你好!’);
out.end();
}) 
此代码确实创建了
/tmp/test.txt
,但没有输出任何内容,文件为空。

此代码有什么问题?

您不需要使用
fs.WriteStream
解决承诺,因为它的创建是同步的。只需直接调用
fs.createWriteStream()
,并将实例传递给您的函数,以创建一个承诺,在流关闭或出现错误时解决:

#!/usr/bin/env node

import fs from 'fs';
import stream from 'stream';

function promisify(s: stream.Stream): Promise<void> {
  return new Promise<void>((resolve, reject) => {
    const onClose = () => {
      s.off('error', onError);
      resolve();
    };
    const onError = (error: Error) => {
      s.off('close', onClose);
      reject(error);
    };

    s.once('close', onClose);
    s.once('error', onError);
  });
}

const out = fs.createWriteStream('/tmp/test.txt');

promisify(out).then(() => {
  console.log('Done');
});

out.write('Hello!');
out.end();
#/usr/bin/env节点
从“fs”导入fs;
从“流”导入流;
函数promisify(s:stream.stream):Promise{
返回新承诺((解决、拒绝)=>{
const onClose=()=>{
s、 关闭(“错误”,onError);
解决();
};
const onError=(错误:error)=>{
s、 关闭(“关闭”,关闭);
拒绝(错误);
};
s、 一次(“关闭”,一次关闭);
s、 一次(“错误”,一次错误);
});
}
const out=fs.createWriteStream('/tmp/test.txt');
承诺(出去)。然后(()=>{
console.log('Done');
});
出去。写(‘你好!’);
out.end();

当流关闭时,
createStream
返回的承诺似乎得到了解决,因此在
then
回调中,您将尝试在这之后写入。我读对了吗?是的,
createStream
承诺在流关闭时得到解决。由于没有人关闭这条河流,因此承诺尚未兑现。这就是为什么从来没有调用
then
函数的原因。我不知道,当队列中有任务时,节点不应该退出。您的情况是“我的桶里有个洞,亲爱的莉莎,亲爱的莉莎”。(1)
.then(…)
处理程序在承诺实现之前不会被调用。(2) 只有当文件流关闭时,承诺才会实现。(3) 文件流仅由
处理程序中的一条语句关闭。然后(…)
处理程序。@jonrsharpe可写流不会创建保持事件循环运行的引用,承诺也不会。这就是程序退出的原因。