본문 바로가기
Programming

[Javascript] 자바스크립트 fs 모듈 사용하기 (Promise, async/await 사용)

by 개발자 염상진 2022. 5. 18.

 

 

Node.js API fs모듈

 

Node.js는 비동기 이벤트 기반 Javascript 런타임 환경이다. 웹 브라우저에서 지원하지 않는 다양한 비동기 API들을 지원하고 있다. Node.js는 웹 브라우저를 벗어나서 로컬 환경에서 Javascript를 실행할 수 있다. 

 

Node.js 내장 모듈 모음

 

Javascript를 로컬 환경에서 작동시킬 때 가장 흔한 IO가 파일이다. 파일을 읽기 위해서는 파일 시스템 모듈(fs)를 사용할 수 있다.

 

const fs = require('fs');

 

 

fs 모듈 파일 읽어오기

 

웹 브라우저를 벗어난 Node.js 환경은 로컬 컴퓨터에서 실행되면서 파일을 읽어올 수 있다. 

 

fs 모듈 공식 문서

 

reaFile 메소드는 비동기적으로 파일 내용 전체를 읽어온다. 

fs.readFile(path[, options], callback);

 

① path는 파일 이름을 인자로 받는다. [string / Buffer / URL / Integer] 4가지 중 한가지를 인자로 받을 수 있다.

② 두번째 인자는 객체 혹은 문자열을 넘길 수 있다. 문자열을 넘기는 경우 인코딩을 넘기게 된다. 

③ 마지막 인자는 callback 함수를 전달받는다. 파일을 읽은 후 비동기적으로 실행되는 함수다. 

 

fs.readFile('test.txt', 'utf-8', (err, data)=>{
	if(err)
    	throw err;
        
    console.log(data);
})

 

콜백함수 사용 readFile()

filePath와 콜백함수를 받아서 데이터를 읽어오는 getDataFunc() 메소드를 아래 처럼 구성할 수 있다.

const fs = require("fs");

const getDataFunc = function (filePath, callback) {

  fs.readFile(filePath, 'utf-8', (err, data)=>{
    if(err)
      callback(err, null);
    else
      callback(null, data);

  })
};

getDataFromFile("test.txt", (err, data)=>{console.log(data)})

 

Promise 사용 readFile()

readFile 메소드를 Promise를 사용해서 구현할 수 있다. 매개변수로는 filePath만 받게 되고 Promise를 반환하는 함수를 아래 처럼 구현한다.

const fs = require("fs");

const getDataFromFilePromise = filePath => {
    
    return new Promise((resolve, reject)=>{
      fs.readFile(filePath, 'utf-8', (err, data)=>{
      if(err)
          reject(err);

      else
        resolve(data);
    })
  })
};

 

 

Promise then~catch 사용 readFile()

Promise와 JSON.parse() 메소드를 사용해서 여러개의 Promise를 then으로 연결해 한번에 출력값을 뽑아낼 수 있다.

 

const fs = require("fs");

const user1Path = path.join(__dirname, 'files/user1.json');
const user2Path = path.join(__dirname, 'files/user2.json');

const getDataFromFilePromiseFunc = filePath => {
    
    return new Promise((resolve, reject)=>{
      fs.readFile(filePath, 'utf-8', (err, data)=>{
      if(err)
          reject(err);

      else
        resolve(data);
    })
  })
};

const readAllUsersChainingFunc = () => {

    const result = [];
    
    return  getDataFromFilePromiseFunc(user1Path)
              .then((values)=>{
                let parsed =  JSON.parse(values)
                result.push(parsed);
                return getDataFromFilePromise(user2Path)
              })
              .then((values)=>{
                let parsed = JSON.parse(values);
                result.push(parsed);
                return result
              })
}

 

 

Promise.all() 사용 readFile()

Promise객체의 all() 메소드를 사용해서 위와 같은 로직을 구현할 수 있다. Promise.all() 메소드를 사용하면 모두 fulfilled 상태의 Promise 값들을 배열 형태로 리턴하게 된다. 

 

배열로 반환받은 values를 map() 메소드를 사용해서 JSON.parse()로 배열의 각 요소들을 변환해주고, 새로운 배열을 반환한다.

 

const fs = require("fs");

const user1Path = path.join(__dirname, 'files/user1.json');
const user2Path = path.join(__dirname, 'files/user2.json');

const getDataFromFilePromiseFunc = filePath => {
    
    return new Promise((resolve, reject)=>{
      fs.readFile(filePath, 'utf-8', (err, data)=>{
      if(err)
          reject(err);

      else
        resolve(data);
    })
  })
};

const user1Path = path.join(__dirname, 'files/user1.json');
const user2Path = path.join(__dirname, 'files/user2.json');

const readAllUsersFunc = () => {
 
  const userPromise1 = getDataFromFilePromiseFunc(user1Path);
  const userPromise2 = getDataFromFilePromiseFunc(user2Path);

  return Promise.all([userPromise1, userPromise2])
      .then((values)=>{
          return values.map((item)=>JSON.parse(item));
      })

}

 

 

async / await 사용 readFile()

readFile 메소드를 async / await 명령어를 사용해서 구현할 수 있다. async가 붙은 함수는 비동기식으로 작동하게 되고, await앞에서 로직을 멈추고 Promise 반환을 기다리게 된다.

만약 fulfilled 된 Promise가 반환되면, Promise의 콜백함수를 마이크로태스크 큐에 넘기게 되고, rejected된 Promise가 되면 예외 처리를 해줘야 한다.

 

const fs = require("fs");

const user1Path = path.join(__dirname, 'files/user1.json');
const user2Path = path.join(__dirname, 'files/user2.json');

const getDataFromFilePromiseFunc = filePath => {
    
    return new Promise((resolve, reject)=>{
      fs.readFile(filePath, 'utf-8', (err, data)=>{
      if(err)
          reject(err);

      else
        resolve(data);
    })
  })
};

const user1Path = path.join(__dirname, 'files/user1.json');
const user2Path = path.join(__dirname, 'files/user2.json');

const readAllUsersAsyncAwait = async () => {

      const result = []
      const a = await getDataFromFilePromiseFunc(user1Path)
      result.push(a);
      const b = await getDataFromFilePromiseFunc(user2Path)
      result.push(b);
      return result.map((item)=>JSON.parse(item));
  
}

 

 

 

 

 

 

[Javascript] async await 사용방법

ES8 비동기 처리 방법 ES8(ECMAScript 2017)에서 비동기 처리 방식으로 async / await가 도입되었다. Promise를 기반으로 작동하고, then/catch/finally 후속 처리 메소드에 콜백함수를 전달해서 비동기 처리 결..

about-tech.tistory.com

 

댓글