개발/알아둘 기본 개념
동기 & 비동기
후누피
2023. 12. 23. 15:23
728x90
👉 들어가면서...
동기방식은 코드순서대로 실행되기때문에,
위의 코드가 완료되지않으면, 완료될때까지 기다렸다가, 다음코드가 실행된다.
하지만, 이러한 방식은 효율적이지 못하기때문에
비동기방식을 사용한다.
비동기방식은 먼저 완료된 코드부터 실행되는 방식이다.
동기방식은 이어달리기라고 생각하면될거같다.
👉 코드
//동기적 방식
function taskA() {
console.log("A작업 끝");
}
taskA();
console.log("코드 끝");
//비동기적 방식
function taskB(a, b, cb) {
setTimeout(() => {
const res = a + b;
cb(res);
}, 3000);
}
function taskC(a, cb) {
setTimeout(() => {
const res = a * 2;
cb(res);
}, 1000);
}
function taskD(a, cb) {
setTimeout(() => {
const res = a * -1;
cb(res);
}, 2000);
}
taskD(2, (res) => {
console.log("D TASK RESULT :", res);
});
taskB(3, 4, (res) => {
console.log("B TASK RESULT :", res);
});
taskC(5, (res) => {
console.log("C TASK RESULT :", res);
});
console.log("코드 끝2");
1. 동기적 방식에서는 taskA();가 실행이 다 완료되고, 코드끝이 출력될것이다.
2. 비동기적 방식을 확인하기위해,
setTimeout을 사용하여 확인했다.
비동기적 방식에서는 "코드 끝2"가 먼저 실행이되고,
setTimeout으로인해, taskC,taskD,taskB 순서대로 실행되어
"코드 끝2"
"C TASK RESULT"
"D TASK RESULT"
"B TASK RESULT"
가 실행 될 것 이다.
"쓰레드"가 코드를 실행해주는 단위인데,
그럼 동시에 코드를 여러개 실행해주게 쓰레드를 여러개 사용하면 되지않나? 라는 생각이 들었지만
자바스크립트는 싱글쓰레드기반이기 때문에, 비동기방식을 사용한다.
👉자바 스크립트 엔진은 동기적코드, 비동기적 코드를 어떻게 구분할까?
Heap - 변수 , 상수들에 사용되는 메모리를 저장하는 영역
Call Stack - 작성한 코드의 실행에 따라 호출 스택을 쌓는 영역 (가장 마지막에 들어온 것부터 가장 먼저 제거)
ex)
function one() {
return 1;
}
function two() {
return one() + 1;
}
function three() {
return two() + 1;
}
console.log(three());
동기적 방식 처리 순서.
1. 코드가 실행되며, Call Stack에 Main Context가 쌓인다.
2. console.log(three()); 코드가 실행되어, three()함수가 호출되며 Stack영역에 쌓인다.
3. three()함수가 완료되기 전, two()함수가 호출되며 Stack영역에 쌓인다.
4. two()함수가 완료되기 전, one()함수가 호출되어 Stack영역에 쌓인다.
5. one()함수가 실행되고, 완료되어, Call Stack영역에서 제거된다. (1값을 리턴)
6.two()함수가 실행되고, 완료되어 , Call Stack영역에서 제거된다. ( 리턴받은 1값+1=2값 리턴)
7.three()함수가 실행되고, 완료되어 Call Stack영역에서 제거된다 (리턴받은 2값+1 =3값 )
8.console.log(three())를 통해 리턴 값 3이 리턴이되어 출력된다.
9.Main Context까지 Call Stack에서 제거되며 프로그램이 종료된다.
자바스크립트는 Call Stack이 하나이기 때문에, 싱글스레드라고 생각하면 된다!
비동기적 방식 처리순서.
function asyncAdd(a,b,cb) {
setTimeout(()=> {
const res = a+b;
cb(res);
},3000);
}
asyncAdd(1,3,(res) => {
console.log("결과 :" , res);
});
1. 프로그램이 실행되며 Call Stack에 Main Context추가된다.
2. asyncAdd()함수 호출부가 가장먼저 호출된다. Call Stack에 asyncAdd()가 추가된다.
3. asyncAdd()함수 안에서 setTimeout() 과 cb()함수가 Call Stack이 아닌 Web APIs에 넘겨준다.
4. setTimeout()함수와 cb()함수는 Web APIs에서 계속 실행되고있고, asyncAdd()함수가 call Stack에서 먼저 제거된다.
5. setTimeout()함수가 3초가지나고 WebAPIs에서 제거되고, cb()함수가 Callback Queue로 옮겨진다.
6. Event Loop가 Callback Queue에서 Call Stack으로 cb()함수를 넘겨줄건데, event loop가 CallStack에 Main Context외에
다른 함수가 남아있는지 확인 후 남아있지않으면, 콜백함수를 넘겨줘 cb()함수가 넘겨져서 실행되고, 제거되며 결과 출력 후 프로그램이 종료된다.
728x90