혹시나 잘못된 개념 전달이 있다면 댓글 부탁드립니다. 저의 성장의 도움이 됩니다
비동기 이벤트 기반 자바스크립트 런타임
효율성을 위해 non-blocking과 비동기적으로 작동
공식문서에서 해당 내장 모듈의 사용법 숙지학고 파일 최상단에 모듈을 require()
로 불러옴
-> Node.js 가 설치되면 모듈도 설치된 상태(빌트인)
cf. 모듈 : 하나의 기능을 수행하는 것으로, 조립하여 사용할 수 있음
require()
const fs = require('fs') // file system 모듈 호출
const dns = require('dns') // dns 모듈 호출
3rd-party 모듈
공식적인 빌트인 모듈이 아닌 외부 모듈을 의미
-> npm으로 다운로드, 설치 필요
파일을 읽거나 저장하는 기능을 하는 모듈
readFile()
비동기적으로 파일을 읽음
cf. readFileSync()
는 동기적으로 파일을 읽음
fs.reaFile(path, option, callback)
// path : 파일의 경로, 주로 문자열로 받음
// option : 인코딩 방식(생략 가능)
// callback : 파일을 읽고 난 후에 동작하는 함수 (전달인자 err, data 2가지를 받음)
// cf. option을 생략할 경우 callback의 data 전달인자에 Buffer 객체가 전달됨
// -> 두번째 argument는 생략보다 값을 써주는 것 추천
const fs = require('fs')
fs.readFile('test.txt', 'utf8', (err, data) => {
if (err) {
throw err;
}
console.log(data);
});
// 에러 없으면 null 전달
// data은 파일 내용으로 문자열이나 Buffer(객체) 전달
import { readFile } from 'fs';
readFile('/etc/passwd', (err, data) => {
if (err) throw err;
console.log(data);
});
// ES6 이후에는 import로도 사용 가능(호환 안되는 경우도 있음)
Promise의 resolve, reject의 차이
: Promise에 전달하는 콜백함수(executor)의 전달인자로 resolve는 요청이 성공할 때 수행되며, reject는 에러가 발생하는 등의 요청이 거부되었을 때 수행
resolve()
, reject()
의 전달인자의 활용
: executor의 완료 혹은 실패할 경우 리턴값으로 전달되는 값을 의미
-> 이어지는 프로미스 메서드에 전달인자로 사용
const resolveInSomething = new Promise((resolve, reject)=>{
resolve('hello'); // 'hello' 전달
})
const resolveInNothing = new Promise((resolve, reject)=>{
resolve(); // undefined 전달
})
resolveInSomething.then((result) =>{console.log(result)}) // 'hello'
resolveInNothing.then((result) =>{console.log(result)}) // undefined
Promise 인스턴스에 있는 메서드 종료와 용도
then
: 성공시 수행되는 내용catch
: 오류 발생시 수행되는 내용finally
: 이어진 작업중에 오류가 발생하더라도 수행되는 내용Promise의 메서드의 리턴
Promise를 리턴하여 계속하여 Promise 메서드를 사용할 수 있음 -> Promise Chaining
그리고 다음에 이어지는 메서드에는 콜백함수의 return값이 전달
Promise의 3가지 상태
reject()
, resolve()
가 없는 상태await
키워드 다음에 등장하는 함수
: Promise를 반환하는 형태의 함수
-> callback 방식으로 정의한 함수에는 await
의 의미가 반영되지 않음
await
키워드를 사용할 때 리턴되는 값
: Promise가 아닌 resolve()
나 reject()
의 전달인자가 반환
const sleep = (wait) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve("hello");
}, wait);
});
};
let returnValue = await sleep(1000);
console.log(returnValue); // hello
callback 방식으로 Error 처리
-> callback의 전달인자를 null 처리
공식문서 callback 참조
const fs = require("fs");
const getDataFromFile = (filePath, callBack) => {
fs.readFile(filePath, 'utf-8', (err, data)=>{
if(err){
callBack(err,null);
} else {
callBack(null,data);
}
});
};
getDataFromFile("README.md", (err, data) =>{
console.log(data);
});
// readFile()의 option 전달인자 생략한 경우 Buffer로 반환되므로 인코딩 방식 추가함
Promise를 반환하는 메서드를 활용하여 2가지 파일의 내용을 배열에 담아서 반환하는 함수
getDataFromFilePromise()
를 이용해, 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');
const readAllUsersChaining = () => {
return getDataFromFilePromise(user1Path)
.then((user1)=>
getDataFromFilePromise(user2Path)
.then((user2)=> [JSON.parse(user1), JSON.parse(user2)]));
}
readAllUsersChaining();
Promise.all()
적용하여 배열 반환const readAllUsers = () => {
return Promise.all([getDataFromFilePromise(user1Path),getDataFromFilePromise(user2Path)])
.then((arr) => arr.map((el)=> JSON.parse(el)))
}
readAllUsers();
Promise.all()
의 전달인자
Promise.all()
에 연결된 then()
, catch()
의 매개변수의 형태
: 단일 배열이 전달되며 Promise.all()
이 성공적으로 수행되면 then()
에 값이 전달되고, 오류가 발생한 경우 catch()
에 값이 전달
서버와의 통신으로 받은 JSON 데이터는 문자열로 전달되어 클라이언트에서 요청한 데이터를 활용하기 위해 JSON 객체로 변환해야함. 클라이언트에서 서버로 데이터를 전송할 때도 JSON 데이터를 문자열로 변환해서 보내야하는데 단순히 객체를 문자열로 변환하는 메서드를 사용할 경우 JSON으로서의 역할을 하기 어려움
JSON.parse()
-> 서버에서 받은 데이터에 적용JSON.stringify()
-> 서버로 요청 보낼 데이터에 적용JSON 형태의 문자열을 입력받아 객체로 변환
-> 문자열인 데이터를 서버와 주고 받을 때 사용
↔ JSON.stringify() : 객체를 JSON 문자열로 변환
JSON.parse(text, reviver);
// text만 필수 입력
// text : JSON 형식의 문자열(아닐 경우 오류 발생)
// reviver : 문자열을 JSON으로 변환 후 적용하는 함수로 값을 변경
JSON.stringify(value, replacer, space)
// value 외에는 생략 가능
// value : JSON 문자열로 변환할 대상
// replacer : 문자화 하기 전 value를 가공하는 함수
// space : 가독성을 위해 문자열로 변환할때 공백 삽입 -> 1~10까지의 숫자
cf. 파싱 : 구문에서 원하는 데이터를 추출하고 가공하는 것
cf. JSON(JavaScript Object Notation) : 서버와 데이터를 주고받을 때 교환되는 데이터 폼
-> key : value
쌍으로 이루어진 데이터
cf. 서버와 클라이언트는 서로 데이터를 주고 받을 때 문자열로 전달
여러개의 Promise가 전달될 때 한번에 실행할 수 있는 방법
: Promise 여러개를 배열 형태로 전달받아 단일 배열 형태(Promise)로 반환
Promise.all(iterable);
// iterable : Promise를 요소로 갖는 배열 -> iterable 객체
// cf. Promise가 아닌 요소를 갖는 경우에도 수행됨
전달인자 : 배열 형태(요소 -> Promise)
then()
, catch()
에는 배열 형태로 전달
Promise가 없는 빈 배열을 입력받을 경우, then()
으로 []
빈 배열이 전달
-> fulfilled 상태(동기적으로 수행)
reject 된 Promise를 1개라도 받는 경우, rejected 상태의 Promise를 반환
-> then()
로 다음 작업을 이어가야 하는 경우 resolve 된 Promise를 담은 배열을 전달 받아야함
느낀점
비동기 부분도 그렇고 콜백도 잘 이해를 못했던건가? Node.js fs 모듈 readfile에서 부터 막혀서 3시간중 1시간을 여기에 쏟은 것 같다. 그런데도 잘 이해가 가지않는다. 다행히 내일 오전에 줌 수업이 있어서 들으면 어느정도 이해는 갈 것 같은데 걱정이다. 비동기 중요한데 블로그 정리도 그렇고, 과제도 빨리 쳐내질 못한다. 늘 머리속에 빨리해야한다는 생각만 가득한 것 같다. 오늘 36기 선배님?한데도 물어보니까 빨리 못하면 이해할때까지 시간을 더 할애 하면 된다고하는데... 나 주말도 없이 공부하는데 어떻게 해야하나.. 회고때 try 1순위 목록인 11시에 수면 7시 기상은 한번도 해보질 못했다. 오늘도 벌써 1시다. 맨날 7시정도에 일어나는데 늘 시간이 부족해서 허덕인다. 이러다가 빨리 지치지 않을까 걱정인데 어떻게 해결해야할지 잘 모르겠다. 다른 사람들도 어려워하는거 맞지??
개선점 및 리마인드
promise도 그렇고 mdn 한페이지를 무슨 말인지 몰라서 계속 보고 결국 새탭에 목록들이 가득하다. 한페이지를 봐도 들인 시간에 비해 머리에 남는게 덜 한것 같다. 차라리 이럴바에는 블로그에서 간단하게 어떤 기능을 하는지 알고 심화 과정이 필요한 것만 mdn을 봐야겠다.
**