스트림을 활용한 비동기 순차 처리
스트림을 활용한 비동기 순차 처리
1. 순차적 실행
기본적으로 스트림은 데이터를 순서대로 처리합니다.
Writable 스트림의 _write() 함수는 이전 호출이 callback() 을 호출해 완료될 때까지
다음 데이터 청크를 가지고 호출되지 않습니다.
그리고 Transform 스트림의 _transfrom() 함수 또한 이전 호출이 callback() 을 호출해 완료되어야
다음 데이터 청크를 가지고 호출 됩니다.
이것은 스트림의 중요한 속성으로 각 청크를 올바른 순서로 처리하는데 사용됩니다.
이 속성을 활용해 스트림을 제어 흐픔 패턴에 사용할 수 있습니다.
입력으로 받은 파일 목록을 순서대로 연결하는 concat-file.js 라는 새로운 모듈을 만들어 보겠습니다.
2. concat file 모듈
//concat.js
const { concaFiles } = require('./concat-files.js');
async function main() {
try {
await concatFiles(process.ragv[2], process.argv.slice(3));
} catch (err) {
console.error(err);
process.exit(1);
}
console.log('All files concatenated successfully');
}
main();
// concat-files.js
const { createWriteStream, createReadStream } = require('fs');
const { Readable, Transform } = require('stream');
function concatFiles(dest, file) {
return new Promise((resolve, reject) => {
const destStream = createWriteStream(dest);
Readable.from(files) // (1)
.pipe(new Transform({
objectMode: true,
transform (filename, enc done) { // (2)
const src = createReadStream(filename);
src.pipe(destStream, { end: false });
src.on('error', done);
src.on('end', done); // (3)
}
}))
.on('error', reject)
.on('finish', () => { // (4)
destStream.end();
resolve();
});
});
}
module.exports = concatFiles;
(1) 사용자가 요청한 파일 배열에서 Readable 스트림을 만듭니다.
(2) 각 파일을 처리할 Transform 스트림을 만듭니다. 각 파일에 대해 Readble 스트림을 만들어
파일 내용을 읽고 destStream 으로 파이프합니다. pipe() 옵션에 { end: false } 를 지정해
파일 읽기를 완료된 후에도 destStream 을 닫지 않도록 합니다.
(3) 소스 파일의 모든 내용이 destStream 으로 파이프되면 done() 함수를 호출해
다음 파일의 처리를 시작합니다.
(4) 모든 파일이 처리되면 작업을 종료합니다.