동기(Synchronous) / 비동기(Asynchronous)
자바스크립트는 코드 한 줄씩 순차적으로 실행되는 동기(Synchronous)처리 방식입니다.
자바스크립트를 실행하는 웹브라우저는 스텍(Stack)이라는 코드 실행 공간이 있습니다. 그리고 그 곳에서 코드를 한줄한줄 차례로 실행합니다.
자바스크립트 뿐만 아니라 대부분의 프로그래밍 언어들이 이러한 특징을 가지고 있습니다.
console.log(1);
console.log(2);
console.log(3);
--------------------
결과
1
2
3
그리고 자바스크립트는 비동기(Asynchronous)처리와 유사한 방식을 사용할 수도 있습니다.
예를들어 특정 위치의 코드를 1초 지연한 뒤 코드를 실행하고 싶을 때가 있습니다.
그래서 아래와 같이 setTimeout을 사용하여 2를 1초 뒤에 실행하는 코드를 만들어보았습니다.
console.log(1);
setTimeout(()=>{console.log(2)}, 1000);
console.log(3);
위 코드를 실행하면 결과가 어떻게 나올까요?
결과
1
3
2
코드를 실행하면 1과 3이 바로 나타나며 1초 뒤 2가 결과창에 나오게 됩니다.
일반적으로 동기처리라고 한다면 두번째 줄의 setTimeout의 기간 만큼 코드 진행이 멈췄다가 다시 진행되어야 하는데, 자바스크립트에서는 2라는 답만 1초 뒤에 실행하고 그 뒤의 값들은 2가 실행되지 않아도 출력하고 있습니다.
마치 비동기방식과 유사하게 작동을 하고 있습니다.
이러한 반응을 통해 자바스크립트는 비동기식 처리를 한다고 생각할 수 있지만 실제로는 비동기식처리로 보이는 동기처리방식을 사용하고 있습니다.
웹에서 자바스크립트를 실행할 때, 스택(Stack)에서 코드를 하나하나 실행합니다. 그중에서 시간이 걸린다고 판단되는 코드들은 스택에서 바로 실행하는 것이 아니라 웹 API라는 대기실로 보내어지며 조건이나 계산이 완료되면 큐(Queue)로 보내 스택에 있는 코드가 모두 실행되기를 기다렸다가 스택이 비게 되면 큐에서 스택으로 나머지 코드들을 보내주어 실행하게 됩니다.
웹 API로 넘어가는 코드들은 서버와 통신하는 Ajax요청 코드, 이벤트 리스너, setTimeout 등 과 같이 시간이 필요한 코드들 입니다.
이 현상때문에 싱글스레드인 자바스크립트가 마치 비동기처리를 하는것과 같은 결과를 보여주고 있습니다.
콜백함수
위에서 사용했던 예제와 같은 코드에서 1초 쉰 뒤 2, 3, 4... 같은 순서로 진행되고 싶다면 콜백함수를 사용하여 해결해볼 수 있습니다.
콜백함수란, 어떤 이벤트가 발생했거나 특정 시점에 도달했을 때 시스템에서 호출하는 함수를 말합니다.
쉽게 얘기하자면 A라는 일을 다른 객체에게 시키고, A라는 일을 끝마칠 때까지 대기하는 것이 아니라 A라는 일이 완료되어 실행해야 할 시점에 도달하면 호출하여 실행하는 것 입니다.
setTimeout(function(){콜백함수 안에 넣을 내용}, 1000);
addEventListener('click', function(){콜백함수 안에 넣을 내용});
위 코드의 두 함수는 모두 콜백함수입니다.
setTimeout은 오른쪽의 수치만큼의 시간동안 안에 있는 함수를 기다렸다가 실행을 해주는 콜백함수입니다.
addEventListener는 타겟을 클릭할 때까지 기다렸다가 클릭이 일어나면 실행되는 콜백함수 입니다.
즉, 작성된 코드를 순서대로 실행하면서 위와 같은 콜백함수를 만나면 콜백함수는 패스한 채 다음 순으로 코드를 실행하며 콜백함수의 조건에 도달하게 되었을 때에만 그 시점에서 실행해주게 됩니다.
그 외의 일반 함수에서 콜백함수를 사용하는 예제를 살펴보겠습니다.
function fc1(){
}
function fc2(){
}
fc1();
fc2();
먼저, 위 함수대로 작성을 하게되면 일반적으로 fc1을 실행하고 그 다음 fc2를 실행을 할 것입니다.
하지만 여기서 fc2를 먼저 실행하고 그 뒤에 fc1을 실행하고 싶을때가 있습니다.
function fc1(){
// fc1의 코드를 실행
console.log(1);
}
function fc2(nextfc){
// fc2의 코드를 실행
console.log(2);
nextfc();
}
fc2(fc1);
fc1을 먼저 만들고 fc2를 아래에 만들었지만 실제 함수의 실행은 fc2가 먼저 실행되고나서 fc1을 호출하는 콜백함수를 만들었습니다.
위와 같은 방법으로 콜백함수를 만들게 된다면, 자신이 원하는 순서와 위치에서 함수를 호출할 수 있습니다.
'Web > CS공부' 카테고리의 다른 글
[JavaScript] Promise대신 사용할 수 있는 async / await (0) | 2022.02.24 |
---|---|
[JavaScript] ES6 프로미스(Promise) (0) | 2022.02.23 |
[JavaScript] import / export 를 이용한 모듈 개발 (0) | 2022.02.21 |
[JavaScript] 배열 디스트럭처링(Destructuring) - 구조 분해 할당 (0) | 2022.02.19 |
[JavaScript] getter와 setter (0) | 2022.02.18 |