node.js 교과서 학습 : JS 문법

minseok·2023년 9월 1일
0
post-thumbnail

js진영의 내용을 전체적으로 알아보는 느낌, 처음 js진영을 학습할 때 부분 부분 깊게 들어가는 것 보다 node.js 교과서처럼 전체적인 흐름을 학습하고 후에 부분 부분 디테일을 쌓아가는 것이 좋을 것 같다.

서버관점의 노드

  • 싱글 스레드여서 멀티 스레드방식보다는 컴퓨터 자원을 적게 사용하는 장점이 존재 (CPU core 1개만 사용)
  • I/O가 많은 작업에 적합, libuv로 인해 I/O작업을 OS 프로세스가 non-blocking 방식으로 처리해준다.
  • CPU 집약적인 연산이 많다면 싱글 스레드라는 특징으로 병목현상이 생김

노드를 추천하는 분야

  • 개수는 많지만 크기는 작은 데잍러를 실시간으로 주고 받는 작업(네트워크, DB, DISK작업 같은 I/O에 특화)
  • 채팅 애플리케이션, 주식 차트, JSON 데이터 제공 API 서버

노드를 추천하지 않는 분야

  • CPU 직얍적인 연산이 필요한 분야(이미지, 비디오 처리, 대규모 데이터 처리)



ES2015 문법

var, let, const
ES2015 이상의 문법을 지원하는 환경이면 const, let을 사용하기 권장합니다.

var : 함수 스코프, 호이스팅 O, ~ ES2014
let : 블록 스코프, 호이스팅 X, 변수, ES2015 ~
const : 블록 스코프, 호이스팅 X, 상수, ES2015 ~

	if(true) {
    	var x = 3;
    }
    console.log(x); // 3
    
    if(true) {
    	const y = 3;
    }
    console.log(y); // Uncauht ReferenceError : y us not defined

템플릿 문자열

큰따옴표나 작은따옴표를 사용하여 문자열을 사용하지 않고 백틱('`')을 사용 하는 방식

레거시
	var string = num1 + ' 더하기 ' + num2 + '는 \'...'

템플릿 문자열
    const string = `${num1} 더하기 ${num2} 는'...`    

객체 리터럴

속성명과 변수명이 동일할 때 더 간단한 문법으로 할당할 수 있음

const sayNode = function() {
    console.log('hello');
};

const obj = {
    sayJS() { // sayJS라는 멤버명으로 참조한다.
        console.log('JS');
    },
    sayNode, // sayNode라는 멤버명으로 참조한다.
    [es6]: 'FANSTASTIC', // 객체 리터럴안에서 선언하고 할당할 수 있음
};

{ name, age } // name, age라는 멤버명으로 참조한다.

화살표 함수

(add1, 2, 3, 4), (not1, 2)는 같은 기능을 제공합니다.
기존의 function을 사용하는 방식과의 큰 차이점은 'this binding'입니다.

	function add1(x, y) { // 레거시
    	return x + y;
    }
    
    const add2 = (x, y) => {
    	return x + y;
    }
    
    const add3 = (x, y) => x + y;
    
    const add 4 = (x, y) => (x + y);
    
    function not1(x) { // 레거시
    	return !x;
    }
    
    const not2 = x => !x;

arrow, function내에서 this가 참조하는 값이 서로 다르다.

var relationship1 = {
    name: 'zero',
    friends: ['1', '2', '3'],
    logFriends: function() {
        var that = this;
        this.friends.forEach(function(friends) {
            console.log(that.name, friends); // that를 통해 this를 가져온다.
        });
    }
};

const relationship2 = {
    name: 'apple',
    friends: ['a', 'b', 'c'],
    logFriends() {
        this.friends.forEach(friend => {
            console.log(this.name, friend); // relationship2의 this를 가져온다.
        });
    }
};

비구조화 할당

객체 비구조화

// 레거시 버전
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 candyMachine2 = {
    status: {
        name: 'node',
        count2: 5,
    },
    getCandy() {
        this.status.count--;
        return this.status.count;
    }
};
const { getCandy2, status: { count2 } } = candyMachine2;

배열 비구조화

// 레거시 버전
var array = ['nodejs', {}, 10, true];
var node = array[0];
var obj = array[1];
var bool = array[array.length - 1];

// 새로운 버전
const array2 = ['nodejs', {}, 10, true];
const [node2, obj2, , bool2] = array2;

console.log(node2, obj2, bool2);

프로미스

자바스크립트와 노드에서는 주로 비동기 프로그래밍을 자주 한다.
이벤트 주도 방식 때문에 콜백 함수를 자주 사용하며
ES2015부터는 콜백 대신 Promise를 기반으로 사용됩니다.

const condition = true;
const promise = new Promise((resolve, reject) => {

	// 성공한 경우 resolve를 호출
    // 실패한 경우 reject를 호출
    if(condition)
        resolve('성공');
    else
        reject('실패');
});

promise
    .then((message) => { // 성공한 경우 실행
        console.log(message);
    })
    .catch((error) => { // 실패한 경우 실행
        console.error(error);
    });

기존 nested한 callback으로 표현하는 로직이 평평한 형식으로 표현할 수 있음

promise
    .then((message) => {
        console.log(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);
    });

2개 이상의 Promise도 쉽게 다룰 수 있다.

const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');

// 모든 promise가 resolve(성공)해야 then구문으로 접근
Promise.all([promise1, promise2])
    .then((result) => {
        console.log(result);
    })
    .catch((error) => {
        console.log(error);
    });

asnyc/await

노드 7.6부터 지원되는 기능(ES2017부터 지원합니다.)
콜백 지옥을 프로미스로 탈출하고 async/await으로 한번 더 가독성을 향상시켜붑니다.

Promise 기반 코드

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

async/await 기반 코드

// function 방식
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.log(error);
    }
}

// arrow 방식
const findAndSaveUser = async (Users) => {
    try {
        let user = await Users.findOne({});
        user.name = 'zero';
        user = await user.save();
        user = await Users.findOne({ gender: 'm'});
    } catch(error) {
        console.log(error);
    }
}
const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');

(async () => {
    for await (promise of [promise1, promise2]) {
        console.log(promise);
    }
})();
profile
즐겁게 개발하기

0개의 댓글