코드스테이츠 Pre 17일차

Gary Lee
5 min readMay 27, 2020

--

오늘은 비동기 호출, 타이머 API, this, 그리고 몇가지 함수 메소드에 관해 학습하였다.

동기 vs 비동기 호출

예를 들어 전화와 문자를 하는 상황을 비교해보자. 전화의 경우 일단 하던 일을 멈추고 받아야 하지만(blocking) 문자의 경우에는 일단 확인만 하고 나중에 답장을 해도 상관이 없다.(non-blocking)

따라서 전화의 경우 요청과 동시에 그 결과가 동시에 일어나야만 하지만(synchronous) 문자의 경우 요청에 대한 결과가 반드시 동시에 일어나지만은 않는다.(asynchronous)

그런데 이러한 동기 호출이 굉장히 비효율적인 상황을 낳게 되는 경우가 있다.

예를 들어 카페에서 손님이 커피를 주문하는 경우를 생각해보자.

먼저 손님들의 주문이 동기적으로 작동한다고 가정하자. 그럼 이렇게 될 것이다.

  1. 손님 A가 아메리카노를 주문한다.
  2. 주문을 접수 받은 바리스타가 아메리카노를 내린다.
  3. 손님 A가 주문한 아메리카노를 가져간다.
  4. 손님 B가 카페모카를 주문한다.
  5. 주문을 접수 받은 바리스타가 카페모카를 내린다.
  6. 손님 B가 주문한 카페모카를 가져간다.

얼핏 보면 별다른 문제가 없는 듯 보이지만, 사실 여기에서는 굉장히 비효율적인 상황이 벌어지고 있다. 바로 손님 B는 손님 A가 아메리카노를 주문하여 이를 받아갈 때 까지 주문을 전혀 할 수가 없는 것이다.

반면에 이걸 비동기적으로 작동한다고 가정하자.

  1. 손님 A가 아메리카노를 주문한다.
  • 주문을 접수 받은 바리스타가 아메리카노를 내린다.
  • 손님 A가 주문한 아메리카노를 가져간다.

2. 손님 B가 카페모카를 주문한다.

  • 주문을 접수 받은 바리스타가 카페모카를 내린다.
  • 손님 B가 주문한 카페모카를 가져간다.

여기서 손님들의 주문은 서로와 상관 없이 이뤄지며 이에 대한 응답은 손님들의 주문과는 별개로 이뤄지게 된다.

비동기 호출의 경우 별도의 이벤트 핸들러에 의해 응답이 이뤄지게 되는데, 위의 예시에서는 ‘손님이 주문한 음료가 완성되었을 때’라고 할 수 있다. 그리고 바리스타가 손님을 불러 완성된 음료를 가져가게 하는 것은 일종의 callback이라고 할 수 있다.

타이머 API

setTimeout

일정한 시간 후에 함수를 실행시킨다. return 값으로 임의의 타이머 ID를 반환하는데, 이 타이머 ID는 타이머를 제어하기 위해서 반드시 필요하다. 멈추려면 clearTimeout을 쓰면 된다.

// 타이머를 실행시킨다. return 값으로 임의의 타이머 ID를 반환한다.
setTimeout(callback 함수, 실행 전 기다려야 할 시간);
// 타이머를 멈춘다. 여기서 타이머 ID는 setTimeout이 return 한 타이머 ID 값이다.
clearTimeout(타이머 ID);

참고로 setTimeout과 관련하여 this 문제가 있는데, setTimeoutthis를 통해 인자값을 전달하고자 하는 경우에 무조건 thiswindow로 지정되게 된다. 자세한 내용은 링크 참조.

setInterval

일정한 시간 간격을 가지고 함수를 반복 실행한다. setTimeout과 마찬가지로 임의의 타이머 ID를 반환한다. 멈추려면 clearInterval을 쓰면 된다.

// 일정한 시간 간격을 가지고 함수를 반복 실행한다. return 값으로 임의의 타이머 ID를 반환한다.
setInterval(callback 함수, 반복 간격);
// 반복을 멈춘다. 여기서 타이머 ID는 setInterval이 return 한 타이머 ID 값이다.
clearInterval(타이머 ID);

this

this는 상황에 따라 그 값이 변하게 되는데, 이러한 패턴에는 5가지가 있다.

  1. Global : this가 전역 context에 있는 경우이다. 이 때 thiswindow이다.
  2. Function 호출 : 1번과 마찬가지로 thiswindow이다.
  3. Method 호출 : this는 Method의 부모가 되는 객체(Object)이다.
  4. Construction mode : 생성한 Class를 가지고 new 키워드를 사용하여 새로운 객체를 만드는 경우인데, 이 때 thisnew 키워드를 통해 새로 생성 된 객체가 된다.
  5. .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

.bindthis 값을 미리 Binding 해 놓고 이를 통해 함수 값을 return 받는 method이다.

function.bind(this가 될 객체, binding 할 값);

앞에서 언급했던 setTimeoutthis 문제의 경우 .bind를 통해서 해결할 수 있는데, 다음과 같이 .bind를 통해 this 값을 명시적으로 지정하면 문제가 해결된다.

setTimeout(box.function.bind(box), 4000);

또한 .bind를 통해 다음과 같이 Curring을 구현할 수도 있다.

let bindingFunc = function.bind(myThis, ‘Gary’);

--

--