NodeJS- 더 북 정리 -1

박경현·2022년 10월 17일
0

문법 및 핵심 모듈에 대한 내용을 적어봤다

언어가 어떻게 돌아가는지 핵심을 아니까 확실히 언어에 대한 이해 깊이가 달라졌다!!

AWS EC2를 사용해서 할 때 노드 설치 법
콘솔
$ sudo apt-get update
$ sudo apt-get install -y build-essential
$ sudo apt-get install curl
$ curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash --
$ sudo apt-get install -y nodejs

자바스크립트 문법

const 와 let
블록 스코프임 - 그 범위에서만 사용 가능

const 는 상수 - 다른 값으로 변경 할 거 아니면 const로 왠만하면 적기!
let은 변수

템플릿 문자열

`` 로 감싸서 ${안에 변수 지정 가능}

객체 리터럴

object 객체에 동적으로 속성 추가!

//예전 방식
	var sayNode = function() {
  		console.log('Node');
	};
	var es = 'ES';
	var oldObject = {
  		sayJS: function() {
    		console.log('JS');
  		},
  		sayNode: sayNode,
	};
	oldObject[es + 6] = 'Fantastic';
	oldObject.sayNode(); // Node
	oldObject.sayJS(); // JS
	console.log(oldObject.ES6); // Fantastic

차이점: sayJS 적을때 : 안적음! , sayNode도 이것만 적으면 됨, ES6문법으로 사용하려면 [es+6]라고 적어주기

//최근 방식
var sayNode = function() {
  console.log('Node');
};
var es = 'ES';

const newObject = { 
	sayJS() { console.log(“js”); }

	sayNode,
	[es+6]:’Fantastic’
};
newObject.sayNode() // Node
newObject.sayJS(); // JS
console.log(newObject.ES6); // Fantastic

화살표 함수
const add3 = (x, y) => x + y;

this바인딩 방식이 다르다

var relationship1 = {
	name: ‘zero’,
	friends: [‘nero’,here’,’xero’],
	logFriends: function() {
		var that = this; // relatationship1을 가리키는 this를 that에 저장
		this.friends.foreEach(function(freind) {
			console.log(that.name, friend)
		})
	}
}
	최신 방법
	const relationship2 = {
		name: 'zero',
		friends: ['nero', 'hero', 'xero'],
		logFriends() {
 			this.friends.forEach(friend => {
   				console.log(this.name, friend);
 				});
			},
		};
	relationship2.logFriends();

구조 분해 할당
객체와 배열로부터 속성이나 요소를 쉽게 꺼낼 수 있다

var candyMachine = {
  		status: {
    			name: 'node',
    			count: 5,
  		},
  		getCandy: function () {
    			this.status.count--;
    			return this.status.count;
  		},
	};
var getCandy = candyMachine.getCandy;
var count = candyMachine.status.count;

// 최신 방식
const candyMachine = {
	 status: {
    		name: 'node',
    		count: 5,
  	},
	getCandy() {
		this.status.count--;
    		return this.status.count;
	}

}
const {getCandy, status:{count}} = candyMachine;

const array = [‘nodejs, {}, 10, true]
const [node, obj, ,bool] = array

클래스
프로토타입기반으로 작동함 - 프로토타입 기반 문법을 보기 좋게 클래스로 바꾼거

class Human {
	constructor(type=‘human’) { this.type = type}

	static isHuman(human) { return human instanceof Human}
	breathe() { alert(‘h-a-a-m’) }

}
class Zero extends Human {
	constructor(type, firstName, lastName) { super(type); this.fisrtName= firstName; this.lastName= lastName}

	sayName() { super.breathe(); alert(`${firstName}`)}
}
const newZero = new Zero('human', 'Zero', 'Cho');
Human.isHuman(newZero); // true

프로미스
콜백을 프로미스 기반으로 재구성함

1. 프로미스 객체를 생성하기
2. 프로미스에서 resolve가 실행 될시 then 이 실행
3. reject가 실행될시 catch 가 실행
=> 결국 실행은 바로 하되 결과 값은 나중에 받는 객체!!
=> return 해서 다음 then으로 계속 넘기기 가능!


const condition = true
const promise= new Promise((resolve, reject) => {
	if(condition) { resolve(‘성공’)}
	else { reject(‘실패’)}

})
promise.then((message) => {console.log(message) // 이렇게 하면 성공시 실행됨}
.catch((error) => {console.log(eror)}
.finally() { console.log(‘무조건)}
)

=======

	promise
 		 .then((message) => {
    			return new Promise((resolve, reject) => {
      			resolve(message);
    			});
  		})
  		.then((message2) => {
    			console.log(message2);
    			return new Promise((resolve, reject) => {
      				resolve(message2);
    			});
 		 })
  		.then((message3) => {
    			console.log(message3);
  		})
  		.catch((error) => {
    			console.error(error);
  		});

====
function findAndSaveUser(Users) {
  Users.findOne({})
    .then((user) => {
      user.name = 'zero';
      return user.save();
    })
    .then((user) => {
      return Users.findOne({ gender: 'm' });
    })
    .then((user) => {
      // 생략
    })
    .catch(err => {
      console.error(err);
    });
}

async / await

동기에 좋음
await이 될때 까지 기다림
async function findAndSaveUser(Users) {
  try {
    let user = await Users.findOne({});
    user.name = 'zero';
    user = await user.save();
    user = await Users.findOne({ gender: 'm' });
    // 생략
  } catch (error) {
    console.error(error);
  }
}

AJAX
비동기적 웹 서비스를 개발 할 때 사용하는 기법
페이지 이동없이 서버에 요청을 보내고 응답을 받는 기술
요청은 jQuery axios 같은 라이브러리를 사용

axios get 요청방식
	get에 요청을 보낼 주소를 적고 promise가 자체 내장이라서 then과 catch 가능!
	
	axios.get('https://www.zerocho.com/api/get').then((result)=> {} .catch((error)=> {} )

axios POST 요청방식
	(async () => {
		try {
			const result = await.axios.post('https://www.zerocho.com/api/post/json', {
  				name: 'zerocho',
  				birth: 1994,
				});
		}
		console.log(result)
		catch((error) => { 
			console.log(error)
		}
	})();

FormData
html form 태그의 데이터를 동적으로 제어할 수 있는 기능 주로 AJAX와 함께 사용!

const formData = new FormData();
formData.append(‘name’,’zerocho’)
formData.has(‘name’) // true
formData.get(‘name’) // zerocho
formData.getAll(‘item’) // key 가 item인 녀석을 전부 가져옴!
formData.delete(name’)
formData.set(‘item’,’apple’)

( async() => {
	try {
		const formData = new FormData();
		formData.append(‘name’,’zerocho’)
		const result = await axios.post('https://www.zerocho.com/api/post/formdata', formData);
			console.log(result)

	}catch(error) { console.log(error) }
})()

encodeURIComponent, decodeURIComponent

주소에 한글이 들어가는 경우 서버가 인식 못할 수 도 있다 => window객체 메서드인 encodeURIComponent,사용하면됨
한글 주소 부분만 encodeURIComponent,메서드로 감싸기!

(async() => {
try {
const result = await axios.get(https://www.zerocho.com/api/search/${encodeURIComponent('노드')});
console.log(result);
}catch(error) { console.log(error) }

})()
decodeURIComponent('%EB%85%B8%EB%93%9C'); // 노드

데이터 속성과 dataset
노드를 웹서버로 사용하는 경우 클라와 빈번하게 데이터 주고 받음
보안 고려하기 ! => 보안과 무관한 데이터는 자유롭게 프론트엔드로 보내도 됨
HTML과 관련된 데이터를 저장하는 공식 방법 - data속성

아래 코드를 보면 data- 라고 적혀있는 태그들은 데이터 속성을 가진다
자바스크립트에 쉽게 접근 가능!
data-id의 경우 id가 되고 data-user-job은 userJob이 된다!
  • Zero
  • Nero
  • Hero
  • Kero

worker_threads
노드에서 멀티 스레드 방식으로 작업하는 방법

isMainThread를 통해 현재 코드가 메인스레드에서 실행되는지 아니면 우리가 생생한 워커 스레드에서 실행되는지 구분
메인 스레드에서는 new Worker를 통해 현재 파일을 워커 스레드에서 실행 물론 현재 파일의 else 부분만 워커 스레드에서 실행됩니다.

부모에는 워커 생성후 worker.postMessage로 워커에 데이터 보내기 가능!
worker는 parentPort.on(‘message’)이벤트 리스너로 부모로부터 메시지를 받고 parentPort.postMessage로 부모에게 보냄
부모는 worker.on으로 메시지를 받음 / worker에서는 on메서드르 사용할때는 직접 워커를 종료 해야한다!
parentPort.close()를 하면 부모와의 연결이 종료됨 worker.on(‘exit’)가 실행됨

chile_process
노드에서 다른 프로그램을 실행하거나 명령어를 수행하고 싶을때 사용하는 모듈
다른언어의 코드를 실행하고 결과값을 받을수도 있다
현재 노드 프로세스 외에 새로운 프로세스를 띄어서 명령을 수행하고 노드 프로세스에게 결과를 알려주기 때문

만약 명령어면 stdout과 stderr로 이벤트 리스너에 버퍼형태로 전달됨

const spawn = require('child_process').spawn; => 새로운 프로세스 작동
const exec = require('child_process’).exec; => 명령어를 처리할때

파일 시스템 접근하기
fs모듈은 파일 시스템에 접근하는 모듈 / 웹 브라우저에서 자바스크립트를 사용할때는 일부를 제외하고는 파일 접근 금지

파일 모듈은 readfile을 적은 뒤 파일 경로 적어주고 (err, data) 인수로 받기! -> 버퍼가 출력됨(메모리의 데이터)
data.toString()해야 원본 나옴!
fs는 기본이 콜백 형식 모듈 => promise형식으로 바꿔주는게 실무 이용!

동기 메서드 / 비동기 메서드
노드는 대부분의 메서드를 비동기 방식으로 처리! -> 몇몇 메서드는 동기 방식으로도 사용 가능
비동기 메서드들은 백그라운드에 해당 파일을 읽으라고만 요청하고 다음 작업으로 넘어감
파일 읽기 요청만 세번 보내고 console.log(‘끝’)을 찍음!
읽기 완료되면 백그라운드가 다시 메인스레드에게 알림 메인스레드는 그제서야 콜백 함수 실행

수백개의 I/O 요청이 들어와도 메인스레드는 백그라운드에 위임함! -> 그 후로 계속 요청 받음 -> 백그라운드는 요청 처리 완료 알려주고 메인이 콜백 처리

동기와 비동기 : 백그라운드 작업 완료 확인 여부
블로킹 - 논 블로킹 : 함수가 바로 return 되는지 여부

동기-블로킹 방식에서는 백그라운드 작업 완료 여부를 계속 확인하며, 
	호출한 함수가 바로 return되지 않고 백그라운드 작업이 끝나야 return됩니다.

	동기-블로킹 방식의 경우 이전 작업이 완료될때 까지 즉 백그라운가 작업하는 동안 메인스레드 무한대기!

비동기-논 블로킹 방식에서는 호출한 함수가 바로 return되어 다음 작업으로 넘어가며, 
	백그라운드 작업 완료 여부는 신경 쓰지 않고 나중에 백그라운드가 알림을 줄 때 비로소 처리합니다.

파일을 읽거나 쓰는 방식은 버퍼와 스트림이 있다
버퍼링은 영상을 재생할 수 있을때까지 데이터를 모오는 동작
스트리밍은 영상데이터를 조금씩 전송

노드는 파일을 읽을때 파일 크기만큼 메모리에 공간 만들고 그 후 메모리에 저장! -> 사용자가 조작가능!

const buffer = Buffer.from(‘hello’) -> buffer로 변경
toString(buffer) -> 문자열로 바꿈
concat(배열) -> 배열 안에든 버퍼를 하나로 합침
alloc(바이트) -> 빈 버퍼를 생성 바이트를 인수로 넣으면 이 크기만큼 버퍼 생성

버퍼의 경우 편리하지만 용량 큰 파일 10개 들어오면 메모리 문제 발생할수도있다
그래서 조금씩 계속 전달하는 스트림 방식

const readStream = fs.createReadStream('./readme3.txt',{highWaterMark:16})
	highWaterMark는 버퍼의 크기(바이트)를 정할 수 있는 옵션/ 기본은 64kb
	

스레드 풀 알아보기
비동기 메서드들은 백그라운드에서 실행되고 실행된 후에는 다시 메인 스레드의 콜백 함수나 프로미스의
then부분이 실행 됨 -> 이때 fs 메소드를 여러번 실행해도 백그라운드에서 동시에 처리 => 스레드 풀때문에!

중요한건 들어온 순서에 맞춰서 나오지 않는 다는 것!
에 UV_THREADPOOL_SIZE=1 하고 다시 node  실행하면 -> 스레드 1개만 쓰기 때문에 순서대로!

이벤트 이해하기
.on(이벤트명,콜백) - 이벤트이름과 이벤트 발생시 콜백을 연결, 여러개 작성 가능
.addListener(이벤트명, 콜백) - on이랑 같다
emit(이벤트명) - 이벤트를 호출
once(이벤트명,콜백) - 한번만 실행되는 이벤트
removeAllListeners(이벤트명) - 이벤트에 연결된 모든 리스터 제거
removeListener(이벤트명)

예외처리하기
멀티스레드 프로그램은 스레드 하나면 다른 스레드가 대신함
하지만 노드는 메인스레드가 하나여서 이게 멈출 경우 전체 서버도 멈춤
그래서 에러 로그는 기록되고 계속 진행되게 프로그램 설계

profile
SW로 문제를 해결하려는 열정만 있는 대학생

0개의 댓글