오늘은 비동기 호출, 타이머 API, this, 그리고 몇가지 함수 메소드에 관해 학습하였다.
동기 vs 비동기 호출
예를 들어 전화와 문자를 하는 상황을 비교해보자. 전화의 경우 일단 하던 일을 멈추고 받아야 하지만(blocking) 문자의 경우에는 일단 확인만 하고 나중에 답장을 해도 상관이 없다.(non-blocking)
따라서 전화의 경우 요청과 동시에 그 결과가 동시에 일어나야만 하지만(synchronous) 문자의 경우 요청에 대한 결과가 반드시 동시에 일어나지만은 않는다.(asynchronous)
그런데 이러한 동기 호출이 굉장히 비효율적인 상황을 낳게 되는 경우가 있다.
예를 들어 카페에서 손님이 커피를 주문하는 경우를 생각해보자.
먼저 손님들의 주문이 동기적으로 작동한다고 가정하자. 그럼 이렇게 될 것이다.
- 손님 A가 아메리카노를 주문한다.
- 주문을 접수 받은 바리스타가 아메리카노를 내린다.
- 손님 A가 주문한 아메리카노를 가져간다.
- 손님 B가 카페모카를 주문한다.
- 주문을 접수 받은 바리스타가 카페모카를 내린다.
- 손님 B가 주문한 카페모카를 가져간다.
얼핏 보면 별다른 문제가 없는 듯 보이지만, 사실 여기에서는 굉장히 비효율적인 상황이 벌어지고 있다. 바로 손님 B는 손님 A가 아메리카노를 주문하여 이를 받아갈 때 까지 주문을 전혀 할 수가 없는 것이다.
반면에 이걸 비동기적으로 작동한다고 가정하자.
- 손님 A가 아메리카노를 주문한다.
- 주문을 접수 받은 바리스타가 아메리카노를 내린다.
- 손님 A가 주문한 아메리카노를 가져간다.
2. 손님 B가 카페모카를 주문한다.
- 주문을 접수 받은 바리스타가 카페모카를 내린다.
- 손님 B가 주문한 카페모카를 가져간다.
여기서 손님들의 주문은 서로와 상관 없이 이뤄지며 이에 대한 응답은 손님들의 주문과는 별개로 이뤄지게 된다.
비동기 호출의 경우 별도의 이벤트 핸들러에 의해 응답이 이뤄지게 되는데, 위의 예시에서는 ‘손님이 주문한 음료가 완성되었을 때’라고 할 수 있다. 그리고 바리스타가 손님을 불러 완성된 음료를 가져가게 하는 것은 일종의 callback이라고 할 수 있다.
타이머 API
setTimeout
일정한 시간 후에 함수를 실행시킨다. return 값으로 임의의 타이머 ID를 반환하는데, 이 타이머 ID는 타이머를 제어하기 위해서 반드시 필요하다. 멈추려면 clearTimeout
을 쓰면 된다.
// 타이머를 실행시킨다. return 값으로 임의의 타이머 ID를 반환한다.
setTimeout(callback 함수, 실행 전 기다려야 할 시간);// 타이머를 멈춘다. 여기서 타이머 ID는 setTimeout이 return 한 타이머 ID 값이다.
clearTimeout(타이머 ID);
참고로 setTimeout
과 관련하여 this
문제가 있는데, setTimeout
에 this
를 통해 인자값을 전달하고자 하는 경우에 무조건 this
가 window
로 지정되게 된다. 자세한 내용은 링크 참조.
setInterval
일정한 시간 간격을 가지고 함수를 반복 실행한다. setTimeout
과 마찬가지로 임의의 타이머 ID를 반환한다. 멈추려면 clearInterval
을 쓰면 된다.
// 일정한 시간 간격을 가지고 함수를 반복 실행한다. return 값으로 임의의 타이머 ID를 반환한다.
setInterval(callback 함수, 반복 간격);// 반복을 멈춘다. 여기서 타이머 ID는 setInterval이 return 한 타이머 ID 값이다.
clearInterval(타이머 ID);
this
this
는 상황에 따라 그 값이 변하게 되는데, 이러한 패턴에는 5가지가 있다.
- Global :
this
가 전역 context에 있는 경우이다. 이 때this
는window
이다. - Function 호출 : 1번과 마찬가지로
this
는window
이다. - Method 호출 :
this
는 Method의 부모가 되는 객체(Object)이다. - Construction mode : 생성한 Class를 가지고
new
키워드를 사용하여 새로운 객체를 만드는 경우인데, 이 때this
는new
키워드를 통해 새로 생성 된 객체가 된다. .call
혹은.apply
호출 :this
는.call
이나.apply
에서 첫번째 매개변수에 명시 된 객체가 된다.
몇가지 함수 메소드들
.call & .apply
.call
과 .apply
는 함수에 인자를 전달하기 위해 사용된다. 전달되는 인자값들이 단순한 인자들의 나열이냐 아니면 배열 형태로 전달되느냐의 차이일 뿐 기능상의 차이는 없다.
function.call(this가 될 객체, 인자 값 1, 인자 값 2, …);function.apply(this가 될 객체, 인자 값들의 배열);
또한 배열이 아닌 유사배열에서 배열 method가 필요할 때에도 사용되며, 이 때는 배열 객체의 prototype을 빌려서 사용하게 된다.
예를 들어 DOM을 통해 가져온 유사배열에서 .map
을 사용하고자 하는 경우에는 다음과 같이 사용하면 된다.
Array.prototype.map(DOM으로 가져온 List, 실행하고자 하는 함수);
.bind
.bind
는 this
값을 미리 Binding 해 놓고 이를 통해 함수 값을 return 받는 method이다.
function.bind(this가 될 객체, binding 할 값);
앞에서 언급했던 setTimeout
의 this
문제의 경우 .bind
를 통해서 해결할 수 있는데, 다음과 같이 .bind
를 통해 this
값을 명시적으로 지정하면 문제가 해결된다.
setTimeout(box.function.bind(box), 4000);
또한 .bind
를 통해 다음과 같이 Curring을 구현할 수도 있다.
let bindingFunc = function.bind(myThis, ‘Gary’);