목차
- 4장 요약
- 기본 라우팅 - 04/server5.js
- 5장 요약
- 비동기 vs 동기 처리 (cause: 자바스크립트 싱글 스레드)
- 논블로킹 = 비동기 처리원리( 이벤트 루프 )
- 비동기 처리 하는 방법
지난번, ch1,2,3은 각각 다른 포스팅으로 정리했지만
이번 ch4,5는 이어지는 부분이 있고, ch4 는 내용의 분량이 적은 것 같아
하나의 포스팅으로 쓰려 한다.
4장요약 : 기본 라우팅
라우팅(routing) 이란 클라이언트에서 들어오는 요청에 따라 다른 응답을 하여 해당 함수를 실행하는 것을 말함.
05/server-5.js
// 라우팅 연습하기 (결과 비교 파일 : 04\results\server-5.js)
const http = require("http");
const server = http.createServer((req,res) => {
//요청 메서드와 URL 가져오기
const {method, url} = req;
res.setHeader("Content-Type","text/plain");
//URL에 따라 응답을 다르게 처리
if (method =="GET" && url == "/home"){
res.statusCode = 200;
res.end("HOME");
}else if (method == "GET" && url == "/about"){
res.statusCode = 200;
res.end("ABOUT");
}else{
res.statusCode = 404;
res.end("NOT FOUND");
}
});
server.listen(3000,()=>{
console.log("3000번 포트에서 서버 실행 중");
});
이때, 위에서 req는 요청 객체로 req에 들어간 method와 url을 변수에 저장한다.
res.end() 는 응답을 종료하는 것인데, 문자열이 들어가면, res.write(문자열); res.end() 와 같다.
5장 요약: 비동기 vs 동기 처리 (cause: 자바스크립트 싱글 스레드)
"동기 처리(syncronous)"는 함수가 쓰여진 순서대로 처리하는 것이고,
"비동기 처리(asyncronous)"는 "동기 처리"에 반대이다.
보다 직관적이지 않은 "비동기 처리"를 코드를 통해 알아보자.
05/async-3.js
// 콜백 함수를 사용해 비동기 처리하기 (결과 비교 파일 : 05\results\async-3.js)
const fs = require("node:fs");
fs.readdir("./",(err,files) => {
if (err){
console.error(err);
}
console.log(files);
});
console.log("Code is done.");
디렉터리 안의 파일들을 읽는 함수와 이를 출력하는 함수 2개가 있는데, 후자는 전자 함수의 기능이 끝나야
실행된다.
또한 파일들을 읽는 함수는 비동기적으로 처리되어 "Code is done." 이 먼저 출력된다.
5장 요약:
논블로킹 = 비동기 처리원리( 이벤트 루프 )
블로킹은 특정 라우터를 처리하는데 시간이 오래걸려서 로딩중으로 화면이 뜨고, 클라이언트는 아무것도 할 수 없는 상태를 말한다.
따라서 코드를 작성할 때 블로킹이 생기지 않게 하려면 비동기 처리를 하여 논블로킹 상태를 유지해야 한다.
그렇다면 비동기 처리에서는 어떻게 논블로킹 상태를 유지할까?
기본적으로 노드에서 자바스크립트 코드는 "스택(stack)" 으로 처리된다. 스택은 LIFO 후입선출의 특징을 가지고 있고
노드에서는 먼저 들어온 코드가 '콜 스택'에서 먼저 처리된다.
비동기 처리는 libuv 라는 비동기 처리 라이브러리를 통해 처리 된다.
libuv는 Node API와 "콜백 큐" 라는 구성 요소를 가지고 있다.
콜백 함수가 큐로 처리되는 "콜백 큐" 는 FIFO 선입선출의 특징을 가지고 있고
비동기 함수는 NODE API로 옮겨진다.
그 후, 노드는 콜 스택에서 다시 불러올 함수가 없으면 libuv를 살피고 콜백 큐를 살핀다.
setTimeout 함수는 특정 초가 지나면 콜백 큐로 들어가고,
노드가 콜백 큐를 살폈을때, 있으면, setTimeout 함수를 콜 스택에 옮긴다.
이 과정을 이벤트 루프 라 한다.
5장 요약: 비동기 처리 하는 방법
비동기 처리는 하나의 작업을 다른 작업에 이어서 해야할 때 사용하는 방식이다.
이를 위해 콜백 함수를 사용하는데,
여러개의 콜백함수가 있으면, 콜백 지옥에 빠지기 때문에
프라미스(성공:then, 실패:catch)를 사용한다.
그 이후 새로 등장한 async/await 처리 방법 또한 있는데,
비동기 처리 방식인 3가지 방식을 좀 더 자세히 정리해보자.
콜백함수
콜백함수란
- 콜백함수란, 매개변수로 함수 객체를 전달해서 함수 내에서 매개변수 함수를 실행하는 것을 말한다. 일반적인 변수나 값을 전달하는 것이 아닌 함수 자체를 전달하는 것이다. 함수 내에서 일회용으로 사용하기에 코드의 간결성을 위해 익명 함수 형태로 넣어줘도 된다.
- example
function sayHello(name, callback) {
const words = '안녕하세요 내 이름은 ' + name + ' 입니다.';
callback(words);
}
sayHello("인파", function (name) { // 함수의 이름이 없는 익명 함수
console.log(name);
});
- 콜백함수를 익명 함수로 정의하여 코드의 간결성을 얻을 수 있지만, 더 간결하게 익명 화살표 함수를 정의해 사용할 수 있다.
- example
function sayHello(callback) {
var name = "Alice";
callback(name); // 콜백 함수 호출
}
// 익명 화살표 콜백 함수
sayHello((name) => {
console.log("Hello, " + name);
}); // Hello, Alice
[출처]: https://inpa.tistory.com/entry/JS-📚-자바스크립트-콜백-함수 [Inpa Dev 👨💻:티스토리]
-> 콜백함수를 이해할때 찾은 잘 정리된 블로그
콜백함수의 활용 예시
- 이벤트 리스너로 사용
addEventListener 은 특정 이벤트가 발생했을 때 실행되는 것으로 요 부분에 사용될 수 있다.
let button = document.getElementById("button"); // 버튼 요소를 선택
// 버튼에 클릭 이벤트 리스너를 추가
button.addEventListener("click", function () { // 콜백 함수
console.log("Button clicked!");
});
- 고차함수
// 예시 : 배열의 각 요소를 두 배로 곱해서 새로운 배열을 생성하는 콜백 함수
let numbers = [1, 2, 3, 4, 5]; // 배열 선언
let doubled = []; // 빈 배열 선언
// numbers 배열의 각 요소에 대해 콜백 함수 실행
numbers.forEach(function (num) {
doubled.push(num * 2); // 콜백 함수로 각 요소를 두 배로 곱해서 doubled 배열에 추가
});
console.log(doubled); // [2, 4, 6, 8, 10]
콜백함수 주의할점
콜백함수 내에 this 를 쓰게 되면 이는 전역 객체로 인식된다.
따라서 이를 해결하기 위해 call() 메서드를 사용할 수 있다.
- call()
- 첫 번째 인자로 this 객체 사용, 나머지 인자들은 , 로 구분
// this 대신 userData를 사용하는 방법
let userData = {
signUp: '2021-4-06 12:00:00',
name: 'Not Set',
setName: function(firstName, lastName) {
this.name = firstName + ' ' + lastName;
}
}
function getUserName(firstName, lastName, callback, data) { // userData를 받는 매개변수 data를 추가
callback.call(data, firstName, lastName); // data를 this로 사용
}
getUserName('홍', '길동', userData.setName, userData); // userData를 인수로 전달
console.log('1: ', userData.name); // 홍 길동
console.log('2: ', window.name); // Not Set
프라미스
프라미스란
콜백지옥 (콜백 함수를 사용하면 코드가 복잡해지고 가동성이 매우 떨어지는 상태) 을 마주할 수 있기 때문에 이를 해결하는 프라미스 객체를 사용한다.
promise() 생성자 안에 두 개의 매개 변수를 가진 콜백함수를 넣게 되는데, 첫 번째 인수는 작업이 성공했을 시 (resolve)를 알려주는 객체, 두 번째 인수는 작업이 실패했을 시(reject)임을 알려주는 오류 객체이다.
아래와 같이 프라미스 객체를 생성할 수 있다.
객체 생성
const myPromise = new Promise((resolve, reject) => {
// 비동기 작업 수행
const data = fetch('서버로부터 요청할 URL');
if(data)
resolve(data); // 만일 요청이 성공하여 데이터가 있다면
else
reject("Error"); // 만일 요청이 실패하여 데이터가 없다면
})
객체 생성후, 프라미스 객체 처리를 한다. resolve()를 호출하면 바로 .then() 으로 이어져 추가 처리 진행하고
resolve() 함수의 매개 변수 값이 then() 메소드의 콜백 함수 인자로 들어가 then() 메소드 내부에서 사용할 수 있다. reject()의 경우도 마찬가지다.
객체 처리
myPromise
.then((value) => { // 성공적으로 수행했을 때 실행될 코드
console.log("Data: ", value); // 위에서 return resolve(data)의 data값이 출력된다
})
.catch((error) => { // 실패했을 때 실행될 코드
console.error(error); // 위에서 return reject("Error")의 "Error"가 출력된다
})
.finally(() => { // 성공하든 실패하든 무조건 실행될 코드
})
위와 같이 프라미스 객체를 변수에 할당하는 방식을 사용할 수도 있고, 일반적으로는 별도의 함수로 감싸서 사용한다.
함수 등록
// 프로미스 객체를 반환하는 함수 생성
function myPromise() {
return new Promise((resolve, reject) => {
if (/* 성공 조건 */) {
resolve(/* 결과 값 */);
} else {
reject(/* 에러 값 */);
}
});
}
// 프로미스 객체를 반환하는 함수 사용
myPromise()
.then((result) => {
// 성공 시 실행할 콜백 함수
})
.catch((error) => {
// 실패 시 실행할 콜백 함수
});
-> 위 블로그 참고해서 프라미스 공부함.
async/await
프라미스 또한 콜백 함수와 비슷하게 then() 체인을 길게 이어나가면 가독성이 떨어진다.
이를 해결하기 위해 function 키워드 앞에 async 만 붙여주고, 비동기로 처리되는 부분 앞에 await 만 붙여준다.
또한 async 리턴값은 Promise 객체이다.
// 함수 선언식
async function func1() {
const res = await fetch(url); // 요청을 기다림
const data = await res.json(); // 응답을 JSON으로 파싱
}
func1();
// 함수 표현식
const func2 = async () => {
const res = await fetch(url); // 요청을 기다림
const data = await res.json(); // 응답을 JSON으로 파싱
}
func2();
출처: https://inpa.tistory.com/entry/JS-📚-비동기처리-async-await [Inpa Dev 👨💻:티스토리]
'전공 > node.js' 카테고리의 다른 글
[node.js] 파일 관리하기-path, File System 모듈 (node.js 스터디 1주차-ch3) (0) | 2024.03.20 |
---|---|
[node.js] 자바스크립트 기초문법과 모듈 (node.js 스터디 1주차-ch2) (0) | 2024.03.20 |
[node.js] 실행환경 설정 (node.js 스터디 1주차-ch1) (0) | 2024.03.20 |