Web/Node.JS

Node.js 최신 자바스크립트 트렌드와 프론트엔드 기술 탐구

이영훈닷컴 2025. 2. 6. 00:06
728x90

호출 스택과 이벤트 루프

  • 호출 스택(Call Stack): 함수 호출이 저장되는 LIFO(Last In, First Out) 구조의 스택. 함수 실행이 완료되면 스택에서 제거됨
  • 이벤트 루프(Event Loop): 비동기 처리 시 이벤트나 콜백을 관리하고, 실행 순서를 결정. 태스크 큐(Task Queue)에서 대기하고 있는 콜백을 호출 스택이 비어 있을 때 실행

 

ES2015+ 문법

  • 변수 선언: let, const로 변수 선언 가능. 블록 스코프 지원
  • 템플릿 문자열: 백틱(`) 사용하여 문자열 내 변수 삽입 가능
  • 화살표 함수: 간결한 함수 표현. this가 외부 함수에서 상속
  • 구조 분해 할당: 객체나 배열의 속성을 변수로 쉽게 할당
  • 클래스: 프로토타입 기반 코드를 클래스 문법으로 간결하게 표현 가능
  • 프로미스와 async/await: 비동기 코드의 가독성을 높이고, 콜백 지옥 해결

 

프런트엔드 자바스크립트

  • AJAX: 서버와 비동기적으로 통신하여 데이터를 주고받을 수 있는 기술. XMLHttpRequest 또는 axios 사용
  • FormData: HTML form 데이터를 AJAX 요청으로 송신하기 위해 사용
  • encodeURIComponent / decodeURIComponent: URI의 특정 문자를 인코딩/디코딩
  • 데이터 속성(Data Attribute): HTML 태그에 데이터를 저장하고 dataset을 통해 접근

const와 let

const와 let은 ES6에서 도입된 변수 선언 키워드로, var의 스코프 문제를 해결하기 위해 만들어졌습니다.

  • const: 상수를 선언할 때 사용합니다. 한번 값이 할당되면 변경할 수 없습니다.
  • let: 블록 스코프 지역 변수를 선언할 때 사용하며, 선언된 블록, 문 또는 표현식에서만 유효합니다.
const PI = 3.14; // 값을 변경할 수 없음
let score = 10;  // 블록 스코프 내에서 값 변경 가능

 

클래스 (Class)

클래스는 객체 지향 프로그래밍을 위한 템플릿입니다. 메서드, 생성자, 상속 등을 제공합니다.

class Animal {
    constructor(name) {
        this.name = name;
    }

    speak() {
        console.log(`${this.name} makes a noise.`);
    }
}

class Dog extends Animal {
    speak() {
        console.log(`${this.name} barks.`);
    }
}

const dog = new Dog('Rex');
dog.speak(); // "Rex barks."

 

프로미스 (Promise)

프로미스는 비동기 작업의 성공 또는 실패의 결과를 나중에 처리할 수 있게 해 줍니다. 기본적으로, 프로미스는 세 가지 상

태를 가집니다: 대기(pending), 이행(fulfilled), 거부(rejected). 프로미스의 사용 방법을 이해하기 쉽도록 기본적인 예제를 통해 설명하겠습니다.

const fetchData = new Promise((resolve, reject) => {
    setTimeout(() => resolve("data received"), 3000);
});

fetchData.then(data => console.log(data));

 

프로미스 기본 구조

프로미스는 new Promise 생성자를 통해 생성되며, 이 생성자는 resolve와 reject라는 두 가지 매개변수를 갖는 함수를 인자로 받습니다.

// 예제: 파일 다운로드를 시뮬레이션하는 프로미스
const downloadFile = new Promise((resolve, reject) => {
    // 비동기 작업을 시뮬레이션
    const fileDownloaded = true; // 파일 다운로드 성공 여부
    setTimeout(() => {
        if (fileDownloaded) {
            resolve("파일 다운로드 완료");  // 성공 시 resolve 호출
        } else {
            reject("다운로드 실패");  // 실패 시 reject 호출
        }
    }, 3000); // 3초 후 결과 반환
});

downloadFile
    .then(result => console.log(result))  // 성공 처리
    .catch(error => console.log(error))   // 실패 처리
    .finally(() => console.log("비동기 작업 완료"));  // 최종적으로 항상 실행

 

프로미스 체이닝

프로미스는 여러 비동기 작업을 순서대로 처리할 때 유용하게 사용됩니다. 이를 '프로미스 체이닝'이라고 합니다. 다음 then 호출의 결과는 이전 then 호출의 반환값에 의존합니다.

// 예제: 파일 다운로드 후 파일 분석
downloadFile
    .then(result => {
        console.log(result);  // "파일 다운로드 완료"
        return "파일 분석 시작";  // 다음 then으로 전달
    })
    .then(status => {
        console.log(status);  // "파일 분석 시작"
        return "파일 분석 완료";  // 다음 then으로 전달
    })
    .then(finalResult => console.log(finalResult))  // "파일 분석 완료"
    .catch(error => console.log(error))  // 에러 처리
    .finally(() => console.log("모든 작업 완료"));  // 최종적으로 항상 실행

 

async / await

async와 await는 JavaScript의 비동기 처리 패턴 중 하나로, 기존의 복잡한 프로미스 체이닝(Promise chaining)을 보다 간결하고 동기적인(synchronous) 방식으로 작성할 수 있게 도와주는 문법입니다. 이 문법을 사용하면 비동기 코드를 마치 동기 코드처럼 읽고 작성할 수 있습니다.

 

async/await 기본 개념

  • async 함수: 함수 앞에 async 키워드를 추가하면 해당 함수는 항상 프로미스를 반환합니다. 함수 내부에서 return 문을 사용하면, 이 값은 프로미스에 의해 자동으로 resolve 됩니다. 만약 함수 실행 중 예외가 발생하면, 그 예외는 프로미스의 reject가 됩니다.
  • await 연산자: await 키워드는 async 함수 내부에서만 사용할 수 있으며, 프로미스가 완료될 때까지 함수의 실행을 일시 중지하고, 프로미스의 결과 값을 반환합니다. 프로미스가 거부(rejected)될 경우, await는 예외를 발생시킵니다.
// 프로미스를 반환하는 함수들
function downloadFile(url) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("파일 다운로드 완료");
            resolve("다운로드한 파일 데이터");  // 다운로드된 파일의 내용
        }, 2000);
    });
}

function analyzeFile(data) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("파일 분석 완료");
            resolve("분석 결과");  // 분석된 결과
        }, 2000);
    });
}

// async/await를 사용한 함수
async function processFile(url) {
    try {
        const fileData = await downloadFile(url);  // 파일 다운로드
        const analysisResult = await analyzeFile(fileData);  // 파일 분석
        console.log(analysisResult);
    } catch (error) {
        console.error("에러 발생:", error);
    }
}

processFile("http://example.com/file");

 

이 예제에서 processFile 함수는 async 함수로 선언되었으며, 이 함수 내부에서 downloadFile과 analyzeFile 함수는 각각의 비동기 작업이 완료될 때까지 기다리는데 await를 사용합니다. 두 함수 모두 프로미스를 반환하므로, await를 사용할 수 있습니다. 만약 어느 하나의 작업에서 예외가 발생하면, catch 블록이 실행되어 에러를 처리합니다.

async와 await를 사용하면 프로미스를 사용하는 코드보다 훨씬 가독성이 좋고, 관리하기 쉬운 코드를 작성할 수 있습니다. 이러한 특성 덕분에 복잡한 비동기 로직을 구현할 때 코드의 이해도를 높일 수 있습니다.

 

Map / Set

Map은 키-값 쌍을 저장하는 구조이며, Set은 중복 없는 값을 저장합니다.

let map = new Map();
map.set('name', 'John');
console.log(map.get('name')); // "John"

let set = new Set();
set.add('apple');
set.add('banana');
set.add('apple');
console.log(set.has('apple')); // true
console.log(set.size); // 2
728x90