본문 바로가기

TIL ( CODESTATES)

node.js가 어떻게 파일을 읽나 ( fs.readFile / callback, promise, async&await 구현)

과제 내용

브라우저 환경과는 다르게 node.js 앱은 내 컴퓨터에서 직접적으로 실행되기 때문에 파일을 불러오거나 저장하는 등의 일이 가능하다.

node.js에서는 파일을 읽는 비동기 함수를 제공한다. 이를 통해 callback, promise, async&awit 구현을 실습해본다.

 

 

fs.readFile 공식 API문서

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

 

path : <string> | <Buffer> | <URL> | <integer>

 - path에는 파일 이름을 인자로 넘기는데 위와 같이 네 가지 타입이 있다. 보통 문자열로 넘긴다.

 

 

options : <Object> | <string>

 - encoding, flag 를 넣어줄 수 있다.

 - optional한 인자로 넣지 않을 수도 있다. 객체 또는 문자열 형태로 넘길 수 있다.

 - If options is a string, then it specifies the encoding. ( 아래 예문에서 string 타입의 'utf8'은 encoding을 넘긴 것)

 

 - encoding, flag 더 공부해보기 **

fs.readFile('/etc/passwd', 'utf8', callback);

 

callback : <function>

 - The callback is passed two arguments (err, data), where data is the contents of the file.

 - If no encoding is specified, then the raw buffer is returned.

 

fs.readFile('/etc/passwd', (err, data) => {
	if(err) {
    	throw err;
    }
    console.log(data);
})

 


callback, promise, async & await 로 구현해보기

- 작성할 내용 : 파일 읽기

 

 

1. Callback

const fs = require("fs") // require 구문을 이용해 파일 시스템 모듈을 불러온다.

const getDataFromFile = function(filePath, callback){
	fs.readFile(filePath, function(err, data) {
   	 if(err){
     	callback(err, null);
     }else{
     	callback(null, data.toString()); //error가 발생하지 않으면 err는 null이 된다.
     }
  	});
}
    

* 왜 data.toString()으로 리턴했지? 

 

 

2. Promise

 

const fs = require("fs");
const {resolve} = require("path");

const getDataFromFilePromise = filePath =>{
  return new Prosmie((resolve, reject) = > {
    fs.readFile(filePath, function(err, data){
      if(err){
        reject(err);
      }else{
      	resolve(data.toString())
      }
    })
  })
};
  		

 


 

 - 작성할 내용 : 앞서 작성한 getDataFromFilePromise 함수를 이용해 files/user1.json과 files/user2.json 파일을 불러와서 합친 뒤 두 객체가 담긴 배열을 만든다.

 

 

3. Chaining

const path = require('path');
const { getDataFromFilePromise } = require('./02_promiseConstructor');

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

const readAllUsersChaining = () {
  return getDataFromFilePromise(user1Path)
  .then(user1) => { // then이 전달받는 parameter는 실행된 함수의 결과값
    return getDataFromFilePromise(user2Path)
    .then(user2) =>{
      return '[' + user1 + ',' + user2 +']'
    });
  })
  .then((result) => JSON.parse(result)) // 파일 읽기의 결과가 문자열이므로 
}					// JSON.parse 메소드를 이용해 JSON포맷의 문자열을 javaScript object로 변환한다.

 

 

4. Promise.all

const path = require('path');
const { getDataFromFilePromise } = require('./02_promiseConstructor');

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

const readAllUsers = () => {
  return Promise.all([	//	Promise.all에 
    getDataFromFilePromise(user1Path),	// 경로 두 개를 담은 배열을 인자로 받는다.
    getDataFromFilePromise(user2Path)
  ]).then(([user1, user2]) => {	// 각각의 결과값을 담은 배열이 들어오면
      return '[' + user1 + ',' + user2 +']' // 하나로 합쳐준다.
  })
  .then((result) => JSON.parse(result))
}

 

 

4. Async & Await

 

const path = require('path');
const { deflateRawSync } = require('zlib');
const { getDataFromFilePromise } = require('./02_promiseConstructor');

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

const readAllUsersAsyncAwait = async() => {
  let user1 = await getDataFromFilePromise(user1Path);
  let user2 = await getDataFromFilePromise(user2Path);
  
  let result = '[' + user1 + ',' + user2 +']' 
  let json = JSON.parse(result);
  return json;
}