개발을 하기에 앞서 Javascript의 동작 방식을 알아보고자 동기, 비동기 방식에 대해 글을 써보려고 한다.
우선 동기에 대해 설명을 하자면 Javascript는 한번에 한가지 일만 순차적으로 처리하는 언어이다. 실행 코드를 위에서부터 아래로 순서대로 실행해가며 하나의 작업이 끝날 때까지 또 다른 코드를 실행하지 않는다.
예를 들어, 카운터에서 음식 주문을 할 경우 음식이 나오고 받을 때까지 다른 사람은 주문을 하지 못하는 것과 비슷하다.
콘솔창에 아래과 같이 입력하고 확인해보면 순서대로 값이 찍히는 것을 볼 수 있는데
이와 같은 동작을 동기라고 부르며, 싱글 스레드 언어라고 한다.
console.log("hi");
console.log("I'm Jiyoung");
==> 실행 결과
다음으로 비동기에 대해 알아보자.
비동기는 어떤 요청에 대한 응답에 관계없이 바로 다음 동작이 실행되는 방식이다. 음식 주문을 한 경우 주문 순서에 관계 없이 음식이 나오는 순서대로 받을 수 있는 경우이다. (진동벨로 음식을 받는 방식)
만약 페이지가 로딩 되거나 어떠한 동작을 할 때 일정 이상의 시간이 걸린다면 페이지는 그 시간 동안 화면에 나타나지
않고 다음 동작에 지장을 주게 된다. 빨리 빨리 민족에게 느리고 응답 없는 웹사이트는 필요하지 않다.
그러므로 비동기적으로 동작을 할 수 있어야 한다.
비동기 함수 대표인 setTimeout()함수로 예를 들어보자.
function test() {
setTimeout(() => {
console.log("2");
}, 3000);
}
function test2() {
console.log("1");
test();
console.log("3");
}
만약 비동기를 알지 못한다면 위의 코드 실행 결과는
순으로 출력이 된다고 생각하겠지만 실제 실행 결과는 아래와 같다.
==> 실행결과
왜냐하면 setTimeout()은 비동기 함수로 3초 뒤에 실행이 되기 때문에 세번째 콘솔이 먼저 출력이 되는 것이다.
위처럼 비동기는 특정 코드의 실행 완료를 기다리지 않은 채 다음 코드를 실행하게 되어 프로그램의 응답성을 높이는 데에도움을 준다.
그러나 이런 비동기에는 문제점이 있는데 바로 코드 실행 순서가 엉키는 일이 생길 수 있다는 것이다.
예를 들어, 클라이언트가 서버에 데이터를 요청한 경우 데이터가 도착하기 전에 화면에 코드를 출력하게 되어 데이터가
나타나지 않게 되는 문제가 생길 수도 있다.
그렇다면 실행 순서도 보장하며 비동기 처리를 할 수 잇는 방법은 무엇이 있을까?
1. 콜백 함수(callback)
콜백 함수란 파라미터로 함수를 전달 받아 함수의 내부에서 실행하는 함수이다.
function sleep(callback) {
setTimeout(() => {
callback();
}, 1000);
}
sleep(() => {
console.log("1");
sleep(() => {
console.log("2");
sleep(() => {
console.log("3");
});
});
});
callback 함수를 이용하여 비동기 처리의 실행 순서를 제어한 예시이다.
sleep함수는 callback이라는 콜백 함수를 1초 후에 실행하는 함수로, 여러 개를 중첩 해서 사용할 경우 코드를 실행 순서에 맞춰 나타낼 수 있다. 그러나 콜백 함수를 여러 개 중첩 하여 사용할 경우 내용 파악이 어려워지고 가동성이 떨어질 수 있는데 이를 ‘콜백 지옥’이라고 한다.
Promise를 사용하면 이런 문제를 해결 할 수 있다.
2. Promise
비동기 처리를 위해 사용되는 객체로 ES6에 도입되었다. Promise 생성자의 사용법은 다음과 같다.
const promise = new Promise(function(resolve, reject) { ….. }):
Promise는 실행하고자 하는 처리를 작성한 함수를 인수로 넘긴다.
-resolve: 함수 안의 처리가 성공했을 때 호출해야 하는 콜백 함수,
이행 상태로서 then() 메서드를 이용하여 처리 결과 값을 받을 수 있다.
-reject: 함수 안의 처리가 실패했을 때 호출해야 하는 콜백 함수,
실패 상태로서 catch() 메서드를 이용하여 에러 결과 값을 받을 수 있다.
Promise를 이용하여 위의 예시를 다시 쓴다면 resolve, then을 이용하여 서로 다른 작업으로 이어지도록 좀 더 제어가 쉽게 표현할 수 있다.
function sleep() {
new Promise((resolve, reject) => {
console.log("1");
resolve();
})
.then(() => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("2");
resolve();
}, 1000);
});
})
.then(() => {
console.log("3");
});
}
아스키/EUC-KR/UTF-8 에 대한 짧은 접근 (7) | 2023.04.24 |
---|---|
"CORS 오류: 왜 발생하고 어떻게 해결할까?" (0) | 2023.04.14 |
[HTML] 엔티티 코드 (Entity Code) (0) | 2023.03.31 |
Cookies, Session, JWT (0) | 2023.03.24 |
WebStrom에서 사용하는 다양한 단축키 모음 (1) | 2023.03.17 |