1. Node.js란?
- 웹 브라우저 바깥에서(윈도우, 리눅스, macOS 등) 자바스크립트 코드를 실행할 수 있는 자바스크립트 런타임 환경
- 자바스크립트 런타임 환경웹 브라우저 환경에서는 웹 페이지에 대한 사용자 인터페이스를 만들고, 사용자와의 상호작용을 관리하며, 웹 서버와의 통신을 처리하는데 사용됩니다. 브라우저의 자바스크립트 런타임 환경은 DOM(Document Object Model), 웹 API (예: Fetch API, Web Storage API 등), 이벤트 루프 및 콜 스택과 같은 요소를 포함합니다.따라서 자바스크립트 런타임 환경은 자바스크립트 코드가 실행되는 특정 컨텍스트를 제공하며, 코드가 어떻게 실행되고, 어떤 API가 사용 가능한지, 코드가 어떻게 스케줄링되고 관리되는지 등을 결정합니다.
- 반면에, Node.js는 웹 브라우저 바깥에서 자바스크립트를 실행할 수 있는 자바스크립트 런타임 환경입니다. 이는 서버 측 애플리케이션 개발에 널리 사용되며, 파일 시스템 작업, 데이터베이스 상호작용, 네트워크 요청 처리 등을 수행할 수 있습니다. Node.js 런타임은 V8 자바스크립트 엔진, 이벤트 루프, Node.js API (예: fs, http, crypto 등) 및 콜 스택을 포함합니다.
- 자바스크립트 런타임 환경은 자바스크립트 코드를 실행하는 데 필요한 모든 소프트웨어 구성 요소를 포함합니다. 이는 웹 브라우저 또는 Node.js와 같은 서버 측 환경을 포함할 수 있습니다.
- 웹서버가 아님. 노드 환경에서 웹서버를 만드는 것
- 특징
- 비동기 I/O 처리(Non-blocking), 이벤트 기반
- 순서대로 처리하지 않음
- 지켜보는 방식/알려주는 방식(이벤트)
- 입출력 비동기 처리
- 빠른 속도
- 단일 쓰레드
- CPU가 프로세스 단위로 작업을 처리할 때, 프로세스 내부에서 동시(같은) 작업을 할 수 있도록 하는 작업 단위
- 멀티 쓰레드 사용 : 효율 높이기 위해
- 프로그래밍 언어 별 쓰레드다른 프로그래밍 언어들, 특히 서버 사이드에서 사용되는 언어들은 다양한 방식으로 구성됩니다. 예를 들어, Java는 멀티 쓰레드를 사용하여 복잡한 서버 애플리케이션을 개발할 수 있습니다. 이는 각 요청마다 새로운 쓰레드를 생성하므로, 동시에 여러 요청을 처리하는 데 유용할 수 있습니다. 그러나, 이는 메모리와 CPU 자원을 많이 사용하게 됩니다.Python은 동기식 프로그래밍 모델을 사용하며, 이는 코드의 실행 순서를 명확하게 만들어 줍니다. 그러나, 이는 I/O 작업 도중 블로킹이 발생하게 만들어, 효율성을 저하시킬 수 있습니다.
- 따라서, 각 언어와 환경은 특정한 유형의 문제를 해결하기 위해 설계되었습니다. 그러므로, 어떤 언어를 사용할 지는 개발하려는 애플리케이션의 종류와 요구 사항에 따라 달라집니다.
- PHP는 다른 접근 방식을 취하며, 각 웹 요청마다 새로운 스크립트 인스턴스를 생성합니다. 이 방식은 상태를 관리하는 것이 더 쉽지만, 이는 웹 서버에 많은 부하를 줄 수 있습니다.
- Node.js는 단일 쓰레드를 사용하는데, 이는 메모리 소비가 적고, 복잡한 동기화 문제를 피할 수 있기 때문입니다. 또한, Node.js의 주요 사용 사례 중 하나는 동시에 많은 수의 연결을 처리하는 것이므로, 쓰레드 기반의 서버보다 효율적입니다. 이는 각 연결마다 새로운 쓰레드를 할당하는 것은 메모리와 CPU를 많이 사용하게 되는 반면, Node.js의 이벤트 드리븐, 비동기적 접근 방식은 이런 부담을 크게 줄여줍니다.
- 비동기 I/O 처리(Non-blocking), 이벤트 기반
- 사용하기 좋은 어플리케이션
- JSON API 기반 어플리케이션
- 싱글페이지 어플리케이션 (SPA)
- 입출력 잦은 거
- 데이터 스트리밍
- 데이터 실시간 다루는 것
2. 자바스크립트 기본
2-1. 변수 선언자
- var : 데이터 타입에 관계 없이 선언 가능, 동일 변수명 재선언 가능
- let : var과 동일하나 동일 변수명 재선언 불가
- const : 동일 변수명 재선언, 변수 값 변경 불가
2-2. 함수
❓ 함수란?
⇒ 일정한 동작을 수행하는 코드
❓왜 사용하는가?
⇒ 반복되는 일 쉽게 처리하기
⇒ 코드 깔끔히 정리하기
⇒ 실수 줄이기
function funName() {
console.log("hello");
}
const func1 = (name) => {
return "Hello " + name;
};
const func2 = (name) => "Hello " + name;
funName();
console.log(func1("정원"));
console.log(func2("Jeongwon"));
// 익명함수 -> 화살표 함수
() => {
console.log("화살표 함수, 람다 함수");
};
// 실행하는 법
(() => {
console.log("화살표 함수, 람다 함수");
})();
let sum = (a, b) => a + b;
console.log("합", sum(10, 20));
2-3. 템플릿 리터럴
백틱과 변수명을 사용하여 문자열과 병합하여 사용
let userName = "Jeongwon";
console.log(`hello ${userName}`);
2-4. 구조분해
객체나 배열에서 원하는 값을 추출하여 변수에 할당하는 방법
const person = {
name: 'Alice',
age: 30,
city: 'Wonderland'
};
// 기존 방식
const name = person.name;
const age = person.age;
const city = person.city;
// 구조 분해 방식
const { name, age, city } = person;
// 함수 정의 시 상자 사용
function greet({ name, age }) {
console.log(`Hello, ${name}! You are ${age} years old.`);
}
const person = {
name: 'Bob',
age: 25
};
greet(person); // 'Hello, Bob! You are 25 years old.'
// 함수 정의 시 상자 사용
function greet({ name, age }) {
console.log(`Hello, ${name}! You are ${age} years old.`);
}
const person = {
name: "Bob",
age: 25,
};
const { name: userName, age: userAge } = person;
greet(person); // 'Hello, Bob! You are 25 years old.'
console.log(`객체 직접 참조 : ${person.name}`);
console.log(`객체 구조 분해 할당 : ${userName}`);
2-5. 클래스
class Car {
constructor(modelName, modelYear, type, price) {
this.modelName = modelName;
this.modelYear = modelYear;
this.type = type;
this.price = price;
}
getModelName() {
return this.modelName;
}
getModelYear() {
return this.modelYear;
}
getType() {
return this.type;
}
}
// const car = new Car({"rullu", 2024, "car", 24000});
// Car 클래스를 사용하여 인스턴스 생성
const myCar = new Car("Toyota", 2022, "SUV", 30000);
// 메서드를 호출하여 속성에 접근
console.log(myCar.getModelName()); // 'Toyota'
console.log(myCar.getModelYear()); // 2022
console.log(myCar.getType()); // 'SUV'
- 클래스 사용한 객체 사용 예제
class User {
constructor(username, email) {
this.username = username;
this.email = email;
this.isLoggedIn = false;
}
login() {
// 로그인 처리 로직
this.isLoggedIn = true;
console.log(`${this.username}님이 로그인했습니다.`);
}
logout() {
// 로그아웃 처리 로직
this.isLoggedIn = false;
console.log(`${this.username}님이 로그아웃했습니다.`);
}
displayUserInfo() {
console.log(`Username: ${this.username}, Email: ${this.email}`);
}
}
// User 클래스를 사용하여 객체 생성
const user1 = new User("Alice", "alice@example.com");
const user2 = new User("Bob", "bob@example.com");
// 객체의 메서드 호출
user1.displayUserInfo(); // 출력: Username: Alice, Email: alice@example.com
user2.displayUserInfo(); // 출력: Username: Bob, Email: bob@example.com
// 로그인 기능 사용
user1.login(); // 출력: Alice님이 로그인했습니다.
console.log(user1.isLoggedIn); // 출력: true
console.log("로그아웃 중");
// 로그아웃 기능 사용
setTimeout(() => {
user1.logout(); // 출력: Alice님이 로그아웃했습니다.
console.log(user1.isLoggedIn); // 출력: false
}, 2000);
2-6. 콜백함수
파라미터로 받은 함수를 호출하면 → 콜백함수
요청한 일이 끝난 후에 실행되는 함수
비동기 함수와 함께 사용되는 주요한 개념
즉 함수를 파라미터로 전달하는 것
오래걸리는 작업이 완료되는 것을 확인, 완료 후 할 일 정해주기
함수를 다른 함수의 파라미터로 전달하여 나중에 실행되도록 하는 것이 바로 콜백 함수입니다. 이것이 콜백 함수가 하는 역할 중 하나에요. 함수를 파라미터로 전달하여 원하는 시점에 실행되도록 할 수 있습니다.
일반적으로 콜백 함수는 비동기 작업이 완료되었을 때 실행되도록 사용됩니다. 함수가 비동기적으로 동작할 때는 결과를 바로 반환하지 않고, 작업이 완료되면 콜백 함수를 호출하여 결과를 전달합니다. 이렇게 하면 코드의 흐름이 중단되지 않고 프로그램이 동시에 여러 작업을 처리할 수 있습니다.
function asyncFunction(param1, param2, callback) {
console.log("1. start > asyncFunction()");
setTimeout(() => {
let sum = param1 + param2;
callback(sum);
}, 1000);
console.log("2. end > asyncFunction()");
}
asyncFunction(3, 4, (result) => {
console.log("4. Result:", result);
});
console.log("3. After asyncFunction() called");
// 1. 웹 애플리케이션에서 AJAX 요청을 보내고, 서버에서 데이터를 받은 후에 UI를 업데이트하는 경우.
function fetchDataAndUpdateUI(callback) {
// AJAX 요청 보내는 코드
// 서버로부터 데이터를 받아오는 비동기 작업
setTimeout(() => {
const dataFromServer = { message: "Hello, world!" };
callback(dataFromServer); // 받아온 데이터를 콜백 함수에 전달
}, 1000); // 1초 후에 콜백 함수 호출
}
// 2. Node.js에서 파일을 읽거나 쓸 때 콜백 함수를 사용하여 파일 작업이 완료된 후에 다음 작업을 수행하는 경우.
function readFileAndProcess(callback) {
// 파일을 읽는 코드
fs.readFile("example.txt", "utf8", (err, data) => {
if (err) {
console.error("Error reading file:", err);
return;
}
callback(data); // 읽은 데이터를 콜백 함수에 전달
});
}
// 3. setTimeout 또는 setInterval과 같은 타이머 함수를 사용하여 특정 시간이 지난 후에 작업을 수행하는 경우.
function performDelayedTask(callback) {
// 일정 시간이 지난 후에 실행할 작업을 처리하는 코드
setTimeout(() => {
console.log("Performing delayed task...");
callback(); // 지정된 시간이 지난 후에 콜백 함수 호출
}, 2000); // 2초 후에 콜백 함수 호출
}
// 4. 이벤트 핸들러를 등록할 때 콜백 함수를 사용하여 이벤트가 발생했을 때 실행할 코드를 지정하는 경우.
function registerEventHandlerAndCallback(callback) {
// 이벤트 핸들러 등록 코드
document.getElementById("myButton").addEventListener("click", callback);
}
// 실제 사용 예시
fetchDataAndUpdateUI((data) => {
console.log("Received data from server:", data.message);
// UI 업데이트 작업 수행
});
readFileAndProcess((data) => {
console.log("File content:", data);
// 파일 데이터를 이용한 추가 작업 수행
});
performDelayedTask(() => {
console.log("Delayed task completed!");
// 추가 작업 수행
});
registerEventHandlerAndCallback(() => {
console.log("Button clicked!");
// 추가 작업 수행
});
# 2. 자바스크립트 기본
3. Node.js 기본 및 활용
모듈
- 재사용
- modules.export{ ~~ }
- require문 → import 문
- 내장 모듈과 객체
4. Node.js로 웹서버 구축하기
간단 서버 실습1 - 클라이언트로부터의 요청 url 확인하기
// 서버 사용을 위해 http 모듈을 불러와 http 변수에 할당한다.
const http = require("http");
// http 모듈로 서버를 생성한다.
let server = http.createServer(function (req, res) {
// 클라이언트 요청의 URL과 메서드를 출력
console.log("Request URL:", req.url);
console.log("req 뭐있냐: ", req.headers);
// 응답 객체 헤더 생성 및 종료
// 상태 코드 200(성공), 응답 타입 text/html
res.writeHead(200, { "Content-Type": "text/html" });
res.end("Hello World!");
});
// listen 함수로 8080 포트를 가진 서버를 실행
server.listen(8080, function () {
console.log("Server is running on <http://localhost:8080>");
});
간단 서버 실습2 - GET 요청 받고 처리하기
var http = require("http"); // url 사용
var url = require("url"); // querystring 사용
var querystring = require("querystring"); // 서버 생성
var server = http.createServer(function (req, res) {
console.log("---- start ----");
var parsedUrl = url.parse(req.url); // url 구성요소 파싱
console.log(parsedUrl);
var parsedQuery = querystring.parse(parsedUrl.query, "&", "=");
console.log(parsedQuery);
console.log("---- end ----");
res.writeHead(200, { "Content-Type": "text/html" });
res.end("Hello node.js!");
});
server.listen(8090, function () {
console.log("Server is running...");
});
이 코드는 Node.js의 기본 모듈인 http, url, 그리고 **querystring**을 사용하여 간단한 웹 서버를 만들고, 클라이언트로부터 받은 URL을 파싱하여 쿼리 스트링 부분을 객체화하여 출력하는 예제입니다.
var http = require("http"); // url 사용
var url = require("url"); // querystring 사용
var querystring = require("querystring"); // 서버 생성
var server = http.createServer(function (req, res) {
console.log("---- start ----");
var parsedUrl = url.parse(req.url); // url.parse()로 url 파싱(객체화)
console.log(parsedUrl);
// querystring.parse()로 url 객체의 query 속성을 키-값 쌍의 객체로 변환
var parsedQuery = querystring.parse(parsedUrl.query, "&", "=");
console.log(parsedQuery);
console.log("---- end ----");
res.writeHead(200, { "Content-Type": "text/html" });
let title = "HOME";
if (parsedUrl.pathname == "/about") {
title = "ABOUT";
} else if (parsedUrl.pathname == "/board") {
title = "BOARD";
}
res.end(`
<!DOCTYPE html>
<html>
<head>
<title>${title}</title>
</head>
<body>
<h1>This is ${title}</h1>
</body>
</html>
`);
});
server.listen(8090, function () {
console.log("Server is running...");
});
각 url path에 대해 html 값 넣기
var http = require("http"); // url 사용
var url = require("url"); // querystring 사용
var querystring = require("querystring"); // 서버 생성
var server = http.createServer(function (req, res) {
console.log("---- start ----");
var parsedUrl = url.parse(req.url); // url.parse()로 url 파싱(객체화)
console.log(parsedUrl);
// querystring.parse()로 url 객체의 query 속성을 키-값 쌍의 객체로 변환
var parsedQuery = querystring.parse(parsedUrl.query, "&", "=");
console.log(parsedQuery);
console.log("---- end ----");
res.writeHead(200, { "Content-Type": "application/json" });
let title = "HOME";
if (parsedUrl.pathname == "/about") {
title = "ABOUT";
} else if (parsedUrl.pathname == "/board") {
title = "BOARD";
}
res.end(JSON.stringify(`{'title': ${title}}`));
});
server.listen(8090, function () {
console.log("Server is running...");
});
json으로 데이터 전송하기
var http = require("http"); // url 사용
var url = require("url"); // querystring 사용
var querystring = require("querystring"); // 서버 생성
var server = http.createServer(function (req, res) {
console.log("---- start ----");
var parsedUrl = url.parse(req.url); // url.parse()로 url 파싱(객체화)
console.log(parsedUrl);
// querystring.parse()로 url 객체의 query 속성을 키-값 쌍의 객체로 변환
var parsedQuery = querystring.parse(parsedUrl.query, "&", "=");
console.log("---- end ----");
res.writeHead(200, { "Content-Type": "text/html" });
let title = "Home";
if (parsedUrl.pathname == "/about") {
title = "About";
} else if (parsedUrl.pathname == "/board") {
title = "Board";
} else if (parsedUrl.pathname == "/users") {
title = "Users";
}
let userName = "";
let userAge = "";
if (parsedUrl.pathname == "/users") {
userName = parsedQuery.name || "unknown";
userAge = parsedQuery.age || "unknown";
} else if (parsedQuery.name === "jeongwon") {
userName = "jeongwon";
} else {
userName = "unknown";
}
let responseBody = `
<!DOCTYPE html>
<html>
<head>
<title>${title}</title>
</head>
<body>
<h1>This is ${title}</h1>
<h3>My name is ${userName}</h3>
`;
if (parsedUrl.pathname == "/users") {
responseBody += `<h3>My age is ${userAge}</h3>`;
}
responseBody += `
</body>
</html>
`;
res.end(responseBody);
});
server.listen(8090, function () {
console.log("Server is running...");
});
// 익명 함수로 바꾸고 콜백 넣기
const http = require("http"); // url 사용
const url = require("url"); // querystring 사용
const querystring = require("querystring"); // 서버 생성
const serverHandler = (req, res) => {
console.log("---- start ----");
const parsedUrl = url.parse(req.url); // url.parse()로 url 파싱(객체화)
console.log(parsedUrl);
// querystring.parse()로 url 객체의 query 속성을 키-값 쌍의 객체로 변환
const parsedQuery = querystring.parse(parsedUrl.query, "&", "=");
console.log("---- end ----");
res.writeHead(200, { "Content-Type": "text/html" });
let title = "Home";
if (parsedUrl.pathname == "/about") {
title = "About";
} else if (parsedUrl.pathname == "/board") {
title = "Board";
} else if (parsedUrl.pathname == "/users") {
title = "Users";
}
let userName = "";
let userAge = "";
if (parsedUrl.pathname == "/users") {
userName = parsedQuery.name || "unknown";
userAge = parsedQuery.age || "unknown";
} else if (parsedQuery.name === "jeongwon") {
userName = "jeongwon";
} else {
userName = "unknown";
}
let responseBody = `
<!DOCTYPE html>
<html>
<head>
<title>${title}</title>
</head>
<body>
<h1>This is ${title}</h1>
<h3>My name is ${userName}</h3>
`;
if (parsedUrl.pathname == "/users") {
responseBody += `<h3>My age is ${userAge}</h3>`;
}
responseBody += `
</body>
</html>
`;
res.end(responseBody);
};
const listenHandler = () => {
console.log("Server is running...");
};
const server = http.createServer(serverHandler);
server.listen(8090, listenHandler);
간단 서버 실습3 - POST 요청 처리
const http = require("http");
const querystring = require("querystring");
const serverHandler = (req, res) => {
const postdata = "";
req.on("data", (data) => {
postdata = postdata + data;
});
req.on("end", () => {
const parsedQuery = querystring.parse(postdata);
console.log(parsedQuery);
res.writeHead(200, { "Content-Type": "text/html" });
res.end("keyName1=" + parsedQuery.keyName1);
});
};
const listenHandler = () => {
console.log("Server is running...");
};
const server = http.createServer(serverHandler);
server.listen(8070, listenHandler);
'활동 > 서울시뉴딜일자리 IT인턴' 카테고리의 다른 글
[뉴딜IT인턴] 10일차 - 데이터 분석을 위한 파이썬 1 (0) | 2024.05.22 |
---|