자바스크립트 동작원리
동기방식
비동기방식
싱글스레드
Call Stack
Heap
WebAPIs
Event Loop
Callback Queue
콜백지옥
자바스크립트가 동작하는 방식
과 매우 큰 관련이 있음 (자바스크립트 엔진동작 원리)동기 방식
: 이렇게 지시한 순서대로 작업하면서 앞에 작업이 끝날 때까지 기다렸다가 바로 뒤에 작업이 실행되는 방식 블로킹 방식
: 어떤 작업이 수행될 때 다른 작업이 수행될 수 없는 방식이건 우리의 일을 수행하는 일꾼인 스레드가 1명 밖에 없어서 그런게 아닌가요?
멀티 스레드
: 오래 걸리는 일이 있어도 다른 일꾼에게 지시하면 되므로 괜찮음비동기 방식
: 이렇게 동기 방식과 다르게 여러 개의 작업을 동시에 수행하는 방식논블로킹 방식
: 이렇게 하나의 작업이 스레드를 점유하지 않고 동시에 진행되는 방식function taskA(){
console.log("A 작업 끝");
}
taskA(); // A 작업 끝
console.log("코드 끝"); // 코드 끝
// 예상했던 것처럼 A 작업 끝이 나온 후 코드 끝이 실행
// setTimeout (타이머를 만들 수 있는 내장 비동기 함수, 2개의 파라미터가 들어감)
// 처음에는 콜백함수를 넣어주고 그 다음에는 delay time(ms초단위)을 넣어준다.
function taskA(){
setTimeout( () => {
console.log("A TASK END")
}, 2000)
}
taskA();
console.log("코드 끝");
// 코드 끝이 먼저 실행 후 A TASK END
// 코드 상으로는 taskA가 먼저지만, 이것을 기다리지 않고
// console.log가 먼저 실행된 후 A TASK END가 실행됨
function taskA(a, b, cb){ // res를 실행할 수 있게 콜백이라는 의미에서 cb로 명명하고 전달
setTimeout( () => {
const res = a + b; // a와 b를 더한 값을 res라는 지역상수에 저장(이 안에서만 유용한)
cb(res); // 이렇게 출력
}, 3000)
}
taskA(3, 4, (res) => {
console.log("A TASK RESULT :", res)}
// res 지역상수를 바깥에서 사용할 수 있게 콜백함수 사용
// 결과값을 파라미터로 받아서
// 이쪽으로 코드의 흐름을 넘겨서 res의 값을 전달받아 정상적으로 출력하도록 해줌
);
console.log("코드 끝");
// 코드 끝이 먼저 실행된 후 파라미터를 더한 결과값인 7이 실행
function taskA(a, b, cb) {
setTimeout( () => {
const res = a + b;
cb(res);
}, 3000);
}
function taskB(a, cb){
setTimeout( () => {
const res = a * 2;
cb(res);
},1000);
}
taskA(3, 4, (res) => {
console.log("A RESULT : ", res);
});
taskB(7, (res)=>{
console.log(B RESULT : ", res);
});
console.log("코드 끝");
// 코드 끝이 실행된 후
// B TASK RESULT : 14가 실행되고 (1초 뒤)
// 마지막으로 A TASK RESULT : 7이 실행됨 (3초 뒤)
// 먼저 호출되었어도 이렇게 차이가 나는 것은 taskB는 1초 기다리고,
// taskA는 3초 기다리기 때문에 그래서 taskB가 먼저 끝남
function taskA(a, b, cb) {
setTimeout( () => {
const res = a + b;
cb(res);
}, 3000);
}
function taskB(a, cb){
setTimeout( () => {
const res = a * 2;
cb(res);
},1000);
}
function taskC(a, cb){
setTimeout( () => {
const res = a * -1;
cb(res);
},2000);
}
taskA(3, 4, (res) => {
console.log("A RESULT : ", res);
});
taskB(7, (res)=>{
console.log(B RESULT : ", res);
});
taskC(14, (res)=>{
console.log(C RESULT : ", res);
});
console.log("코드 끝");
// 코드 끝이 실행되고
// 1초 뒤에 B TASK RESULT : 14가 나오고
// 2초 뒤에 C TASK RESULT : -14가 나오고
// 3초 뒤에 A TASK RESULT : 7이 나옴
✔️ JS Engine은 메모리를 할당하는 Heap
과 코드를 실행하는 Call Stack
으로 이루어져 있다.
✔️ Heap
: 변수나 상수들에 사용되는 메모리를 저장하는 영역
✔️ Call Stack
: 우리가 작성한 코드를 쌓아서 실행하는 영역
✔️ 핵심 Point
프링글스통
과 같다고 생각하기!
Call Stack에 가장 마지막에 들어온 것부터 먼저 제거
되는 거라고 이해하면 됨
스레드는 이 Call Stack 하나만을 담당함
. 이 스레드는 Call Stack의 작동방식대로 명령을 처리한다고 보면 되는데, 그래서 자바스크립트가 싱글 스레드
라고 생각하면 됨Heap
, Call Stack
) 외에 Web APIs
와 Callback Queue
, Event Loop
라는 새로운 구성요소들이 생겨났음JS Engine과 웹브라우저의 상호작용
을 위해서 존재하는데, 그 중 가장 대표적인 상호작용이 바로 비동기방식 처리
임setTimeout을 빨간색으로 표시한 이유는 비동기함수이기 때문에
: 3초를 기다리게 되는 비동기함수가 있을 경우 JS Engine은 Web APIs로 넘겨버림. 그러면 Web APIs로 넘겨진 cb()가 포함된 setTimeout()는 실행이 멈추는 게 아니라 3초를 기다리게 됨. 이렇게 setTimeout() 함수가 Web APIs에 머무르게 되어 바로 다음 코드를 수행할 수 있게 되어 asyncAdd() 함수를 끝낼 수가 있게 되는 것임.✔️ 이것을 자세하게 다룬 이유?!
앞으로 비동기방식의 코드를 작성하게 될 일이 많기 때문에 JS Engine이 비동기방식을 어떻게 처리하는지 알고 있으면 동기방식의 코드와 비동기방식의 코드를 같이 사용했을 때, 이래서 이런 문제가 발생했고, 그러면 이렇게 바꾸면 되겠구나를 떠올리기가 쉬워지기 때문.
// 위의 코드들을 활용, 호출부를 바꿔서 다시 비동기방식처리 이해
function taskA(a, b, cb) {
setTimeout( () => {
const res = a + b;
cb(res);
}, 3000);
}
function taskB(a, cb){
setTimeout( () => {
const res = a * 2;
cb(res);
},1000);
}
function taskC(a, cb){
setTimeout( () => {
const res = a * -1;
cb(res);
},2000);
}
taskA(4, 5, (a_res) => {
// 4와 5를 매개변수로 받아 더한 결과값을 taskB의 인자로 넣기
// taskB에는 a_res, b_res 콜백
// taskC에는 b_res, c_res 콜백
console.log("A RESULT :", a_res);
taskB(a_res, (b_res) => {
console.log("B RESULT :", b_res);
taskC(b_res, (c_res) => {
console.log("C RESULT :", c_res);
});
});
});
console.log("코드 끝");
// 그러면 코드 끝이 가장 먼저 실행 되고
// 3초를 기다렸다가 A RESULT : 9가 나옴
// taskA가 끝난 다음 콜백에서 taskB를 호출하여 taskA의 결과값인 9를 넣어서 호출하면
// 전달받은 인자인 9 * 2를 하여 B RESULT : 18이 나오고
// 18을 taskC의 값으로 전달하여 * -1을 하여 C RESULT : -18이 나오는 것을 확인할 수 있음
✔️ 만약 위와 같은 task가 3개가 아니라 20,30개나 된다면
이렇게 콜백함수가 끝도 없이 이어지게 되는 경우를 만날 수 밖에 없음.
✔️ 비동기처리의 결과를 또 다른 비동기처리의 결과로 이용하는 로직이 계속 길어지게 되면서
콜백함수가 안쪽으로 파고드는 이런 현상을 콜백지옥
이라고 함 (Callback Hell)
✔️ 이런 콜백 지옥을 구원하기 위한 자바스크립트의 비동기 담당 객체인 Promise
가 있음
복습ing