동기 & 비동기
만약 우리가 세 가지의 작업을 다 해야하는 경우에 어떻게 처리를 해야할까? 아래의 코드로 생각해보자.
function taskA() {
console.log("TASK A");
}
function taskB() {
console.log("TASK B");
}
function taskC() {
console.log("TASK C");
}
taskA();
taskB();
taskC();
1
위 코드를 실행하는 경우 자바스크립트의 싱글 스레드 작업 수행 방식을 그림으로 표현하면 다음과 같다.
먼저 자바스크립트는 코드가 작성된 순서대로 작업을 처리한다.
이전 작업이 진행중이면 다른 작업을 수행하지 않고 기다린다.
먼저 작성된 코드를 모두 실행하고 나서 뒤에 작성된 코드를 실행한다.
이렇듯 자바스크립트는 앞에 작업이 끝나야 뒤에 작업이 시작되는데, 이를 동기 방식의 처리라고 한다.
또한, 스레드에서 작업 하나를 수행하고 있을 때, 다른 작업을 할 수 없는 것을 블로킹 방식이라고 한다.
그러나 이러한 방식은 task의 처리시간이 길어질수록 큰 문제를 일으킨다.
그럼 스레드를 늘리면 되지 않을까?
멀티 스레드인 경우, 작업을 분할하여 더욱 빠르게 연산을 처리할 수 있다.
그러나 자바스크립트는 싱글 스레드 이므로 멀티 스레드 작업을 기대할 수 없다.
그렇지만 자바스크립트는 왜 싱글스레드를 채택했을까?
자바스크립트는 웹사이트의 보조적인 기능을 수행하기 위해 만들어진 언어이다. 멀티스레드인 java는 다소 무겁고 어렵다는 인식이 있어 복잡한 작업을 신경 쓸 필요없이 싱글스레드인 형태로 채택되었다.
그렇다면 싱글 스레드인데 어떻게 현재와 같이 빠르게 작업을 처리할 수 있을까?
비동기 작업 방식으로 싱글스레드이지만 작업을 동시에 실행시켜 버린다.
논 블로킹 방식이라고도 하며 먼저 작성된 코드의 결과를 기다리지 않고 바로 실행한다.
그럼 작업이 끝난지는 어떻게 알 수 있을까? 간단하게 콜백함수를 붙여주면 된다.
taskA((resultA) => {
console.log(`A 작업 결과 : ${resultA}`);
}
taskB((resultB) => {
console.log(`B 작업 결과 : ${resultB}`);
}
taskA((resultC) => {
console.log(`C 작업 결과 : ${resultC}`);
}
비동기함수를 구현해보자
function taskA(a, b, callBack) {// a와 b 그리고 callback를 인자로 받는다.
setTimeout(() => { // 실행에 delay를 만들어 주는 setTimeout 함수
const res = a + b; // 실행된 결과값을 res에 담는다.
callBack(res); // 결과값을 callBack에 담는다.
}, 3000); // 3000ms 뒤에 실행되도록 설정한다.
}
taskA(3, 7, (res) => {
console.log("RESULT: ", res); // RESULT: 10
})
console.log("코드 마지막");
위 코드는 taskA라는 함수가 첫 번째 인자와 두 번째 인자를 받아 더하고 그 결과를 callback에 담아 3초 뒤에 결과를 실행시키는 함수이다. 작성된 순서대로라면 taskA의 console.log()가 먼저 찍히고 난 후 console.log("코드 마지막")이 찍혀야 한다.
실제로 실행시켜보면 어떻게 나올까?
"코드 마지막" 이 찍히고 난 후 taskA RESULT: 10이 찍힌다.
이러한 결과로 자바스크립트에서 싱글스레드로 비동기를 구현할 수 있다는 결론이 나온다!
'TIL' 카테고리의 다른 글
[JS] Promise (0) | 2023.06.26 |
---|---|
[JS] Javascript Engine Heap & Call Stack (0) | 2023.06.24 |
[JS] 스프레드 연산자(spread operator) (0) | 2023.06.18 |
[JS] 조건문, 구조분해할당(비구조화할당) (0) | 2023.06.10 |
[JS] 단축평가(단락회로평가) (0) | 2023.06.06 |