동기 synchronous
console.log(1);
console.log(2);
console.log(3);
- 자바스크립트는 싱글 스레드 기반의 언어로, 하나의 작업을 한 번에 처리함.
- 이는 하나의 작업이 완료되어야 다음 작업이 시작됨을 말함. 한 번에 하나 씩 순차적으로 실행.
- 코드의 실행 순서와 결과가 명확하지만, 긴 실행 시간을 가진 작업이 있을 경우엔? 그 작업으로 인해 다음 작업이 멈춰있음.
- 이를 해결하기 위해 Event Loop 라는 메커니즘을 활용하여 비동기 처리를 수행.
Single-Threaded?
- 한 번에 오직 하나의 작업만 처리할 수 있는 시스템 구조. 동기적 특성을 가짐.
Event Loop?
- 자바스크립트의 비동기 처리를 가능하게 하는 핵심 구조.
- 콜 스택, 콜백 큐 등을 이용해 동시성 관리.
- Call Stack : 현재 실행중인 작업과 실행될 함수들이 쌓이는 곳. LIFO(Last In First Out) 순서대로 함수 실행 및 제거.
- Callback Que : 비동기 작업이 완료되면 콜백 함수가 콜백 큐에 쌓임. FIFO(First In First Out) 순서대로 함수 실행.
- 그 외 setTimeOut 등의 메서드를 통해 비동기 처리 지원할 수 있음.
비동기 asynchronous
console.log(1);
setTimeout(() => console.log(2), 1000);
console.log(3);
- 비동기 방식은 작업이 독립적으로 실행됨. 각자 시간표에 따라서 실행!
- 작업이 시작된 후에도 다른 작업을 동시에 실행시킬 수 있으므로 동기 방식에서의 사용성을 개선할 수 있음.
- 오래 걸리는 작업을 실행하는 동안 다른 작업을 실행함으로써 성능 향상과 사용자 경험 개선 등을 위해 사용.
비동기 처리 방식의 문제
function getData() {
var tableData;
$.get('https://domain.com/products/1', function(response) {
tableData = response;
});
return tableData;
}
console.log(getData());
- getData() 를 찍어보면 undefined 출력 됨. 이유는?
- $.get() 로 데이터를 요청하고 받아올 때까지 가디리지 않고 다음 코드인 return tableData 를 실행했기 때문. 따라서 getData() 는 초기 값을 설정하지 않은 tableData의 값 undefined.
- 비동기 처리 방식의 문제를 해결하기 위한 방식으로 콜백 함수가 있음
콜백 함수?
function sayHello(callback) {
console.log('안녕하세요!');
callback();
}
function sayName() {
console.log('제 이름은 Kim입니다.');
}
sayHello(sayName);
- 다른 함수에 인자로 전달되어 특정 시점에 호출되도록 되어 있는 함수. 함수 안에서 호출되는 함수!
- 위 코드
- sayHello 함수는 콜백 함수를 매개변수로 받음.
- sayHello 함수 안에서 "안녕하세요!"를 출력한 후, 콜백 함수인 sayName를 호출하여 "제 이름은 Kim입니다." 출력
- 여기서 sayName 함수가 콜백 함수.
- 콜백 함수를 사용하면 코드의 재사용성이 높아지고 유연한 동작을 구현할 수 있음. 이러한 방식으로 특정 함수에 동작을 전달하여 필요할 때 해당 동작을 실행할 수 있음.
콜백 함수로 비동기 처리 방식의 문제점 해결하기
function getData(callbackFunc) {
$.get('https://domain.com/products/1', function(response) {
callbackFunc(response);
});
}
getData(function(tableData) {
console.log(tableData);
});
- 이렇게 콜백 함수를 사용해 특정 로직이 끝났을 때 원하는 동작 실행.
콜백 지옥
task1(function () {
task2(function () {
task3(function () {
setTimeout(function () {
console.log('마지막 작업 시작');
setTimeout(function () {
console.log('마지막 작업 완료');
}, 1000);
}, 1000);
});
});
});
- 그러나 비동기 작업으로 처리해야 하는 일이 많아질수록 예시 코드처럼 중첩 깊이가 더 깊어지면서 코드가 복잡해짐.
- 코딩 패턴으로 이러한 콜백 지옥을 분리할 수 있지만 Promise 나 async/await를 사용하면 더 편하게 해결할 수 있음.
- 다음 시간엔 스택과 큐, 프로미스, 어싱크/어웨잇을 더 알아봐야겠다.
reference