코드스테이츠 7주차 / fs 모듈 (part-2)

support·2021년 12월 6일
2
post-thumbnail

브라우저 환경과는 다르게 Node.js 환경은 로컬 컴퓨터에서 직접 실행되므로, 파일을 불러오거나 저장하는 등의 액션이 가능합니다. fs(File System) module 사용법을 잘 익힌다면 "파일 열기", "파일 저장하기" 등을 직접 구현할 수 있습니다. Node.js 에서는 파일을 읽는 비동기 함수를 제공합니다. 이를 통해 callback과 Promise 구현해 봅니다.

part2의 목적

텍스트 파일은 자바스크립트 객체가 아니기 때문에
JSON.parse()를 통해서 다른 언어들이 모두 이해할 수 있도록
바꿔줄 수 있어야한다
이때 바꿔준 파일을 readFile을 통해서 파일 하나만 읽을 수도 있어야하고 파일 두개를 합쳐서 읽을 수 도 있어야 한다

1. callBack test case

1번 문제는 파일 하나를 읽어와 콜백함수로 데이터와 에러 작동을 하게 하는 문제다

  1. getDataFromFile › 파일을 읽고 나서 callback이 실행되어야 합니다
  2. 에러가 발생할 경우, callback 첫번째 인자에 에러 객체가 전달되어야 합니다
  3. callback 두번째 인자에 파일 내용이 전달되어야 합니다
const fs = require("fs");

const getDataFromFile = function (filePath, callback) {
  // TODO: fs.readFile을 이용해 작성합니다
  fs.readFile(filePath, "utf8", function (err, data)  {
    if(err){
      callback(err, null)
    }else{
      callback(null, data)
    }
  })
};

module.exports = {
  getDataFromFile
};

// 화살표 함수로도 작성가능

const getDataFromFile = function (filePath, callback) {
  // TODO: fs.readFile을 이용해 작성합니다
  fs.readFile(filePath, "utf8", (err, data) => {
    if(err){
      callback(err, null)
    }else{
      callback(null, data)
    }
  })
};

2. promise test case

2번 문제는 위에서 썼던 내용을 promise로 바꿔써야한다

Promise 형태로 리턴되어야 합니다
then 블록을 통하여 파일 내용이 전달되어야 합니다
에러가 발생할 경우, catch 블록을 통하여 에러 객체가 전달되어야 합니다

const fs = require("fs");
const { promise } = require("sinon");

const getDataFromFilePromise = filePath => {
  // return new Promise()
  // TODO: Promise 및 fs.readFile을 이용해 작성합니다.
  return  new Promise(function(resolve, reject){
    fs.readFile(filePath, "utf8", (err, data) => {
      if(err){
        reject(err)
      }else{
        resolve(data)
      }
    })
  })
};

module.exports = {
  getDataFromFilePromise
};

const 파일읽기현황판 = getDataFromFilePromise('/Users/ijiwon/section_2/im-sprint-async-and-promise/README.md')
console.log(파일읽기현황판) // Promise { <pending> }
//파일읽기현황판 자체는 프로미스 객체로 리턴이 되고 글자로 읽기 위해서는 then을 사용해야 한다
파일읽기현황판.then(result => console.log(result))
// README에 써있는 안녕하세요 출력 

3. basicChaining test case

2번에서 만들었던 프로미스 함수를 사용하는 문제이다
함수의 데이터를 .then으로 받아온뒤 또 연결해 리턴하면 된다
빈배열을 사용할 수도 있고 문자열 자체를 사용할 수도 있다

체이닝의 결과가 Promise 형태로 리턴되어야 합니다
user1.json의 내용과 user2.json 내용을 합쳐 객체로 리턴되어야 합니다
fs module을 직접 사용하지 말고, getDataFromFilePromise을 두 번 사용해야 합니다
Promise.all 또는 async/await을 사용하지 않고 풀어보세요

const { text, json } = require('express');
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');

// HINT: getDataFromFilePromise(user1Path) 및 
//getDataFromFilePromise(user2Path) 를 이용해 작성합니다
// 문자열을 더해서 리턴하는 풀이 방법 
const readAllUsersChaining = () => {
  // TODO: 여러개의 Promise를 then으로 연결하여 작성합니다
  return getDataFromFilePromise(user1Path)
  .then(user1 =>{
    return getDataFromFilePromise(user2Path).then(user2 =>{
      return `[${user1},${user2}]`
    })
  }).then(text => JSON.parse(text))
}

// 빈배열을 선언해 push하는 풀이 방법
const readAllUsersChaining = () => {
  // TODO: 여러개의 Promise를 then으로 연결하여 작성합니다
  let arr = [];
  return getDataFromFilePromise(user1Path)
  .then(user1 =>{
    return getDataFromFilePromise(user2Path)
    .then(user2 =>{
      arr.push(user1)
      arr.push(user2)
      return arr.map(function(data){
        return JSON.parse(data)
      })
    })
  })
}

// readAllUsersChaining();

module.exports = {
  readAllUsersChaining
}

4. promise.all test case

3번 파일과 비슷하지만 promis.all을 사용해 하나로 묶어서 데이터를 관리 할 수있다
그러므로 코드가 짧아진다

Promise 형태로 리턴되어야 합니다
Promise.all을 사용해서 풀어야 합니다
user1.json의 내용과 user2.json 내용을 합쳐 객체로 리턴되어야 합니다

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');

//풀이방법 1
const readAllUsers = () => {
  return Promise.all([
    getDataFromFilePromise(user1Path),
    getDataFromFilePromise(user2Path)
  ])
    .then(([user1, user2]) => {
      return `[${user1},${user2}]`;
    })
    .then(text => JSON.parse(text))
}

// 풀이방법 2
const readAllUsers = () => {
  let user1 = getDataFromFilePromise(user1Path)
  let user2 = getDataFromFilePromise(user2Path)
  return Promise.all([user1, user2])
  .then(val => {
    return val.map(function(data){
      return JSON.parse(data)
    })
  })
}

5. async await test case

async 키워드를 사용한 함수는 AsyncFunction의 인스턴스입니다
await 키워드만 이용해 배열이 리턴되어야 합니다
user1.json의 내용과 user2.json 내용을 합쳐 배열로 리턴되어야 합니다

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');

// 풀이 1
const readAllUsersAsyncAwait = async () => {

 let arr = []

 let user1 =  await getDataFromFilePromise(user1Path)
 let user2 =  await getDataFromFilePromise(user2Path)

 arr.push(JSON.parse(user1))
 arr.push(JSON.parse(user2))

 return arr
}

// 풀이 2
const readAllUsersAsyncAwait = async () => {
 
 let user1 =  await getDataFromFilePromise(user1Path)
 let user2 =  await getDataFromFilePromise(user2Path)
 
 let text = `[${user1},${user2}]`
 let json = JSON.parse(text)
 return json;
}

0개의 댓글