Knock!Knock! 코루틴
이전 글: 코루틴과 파이버
코루틴은 함수, try/catch, if, while 같은 control flow 요소이다. while이 있지만 for도 있고, if가 있지만 switch도 있다. 어느 하나가 필수적인 요소라고 할 수 없지만 어느 경우엔 for가 적절하고 어느 경우엔 while이 적절하고 그런거다. 마찬가지로 함수 call/return이 있지만 코루틴 suspend/resume도 있고, 어떤 경우엔 코루틴이 더 적절해 보이는 경우도 있는 거다.
노크코드
이번 글에서는 코루틴을 이렇게 써 볼 수도 있다는 사례로 간단한 노크코드 기능을 구현해보려 한다. LG G2 에 도입된 노크온 기능이란 게 있었다. 슬립 상태의 스마트폰 화면을 톡톡 치면 켜지는 기능. 여기에 톡톡 두드리는 패턴으로 잠금을 해제하는 기능이 추가되었다. 이것이 노크코드.
여기서 간단히 테스트 해보자. https://codepen.io/jooyunghan/full/LePygq
구현1 : 일반적인 이벤트 핸들러
HTML Element에 click 이벤트 핸들러로 구현해 볼 것이다. 네 번의 클릭이 설정된 코드와 일치하면 통과, 그렇지 않으면 실패.
다음은 클로져의 input
배열에 입력 값을 하나씩 쌓아두었다가 확인한다.
구현2: 코루틴 이벤트 핸들러
다음은 클릭 이벤트를 코루틴으로 전달받는 방법으로 같은 일을 하고 있다. 이벤트는 yield
에서 전달받는다.
코루틴을 이벤트 핸들러로 사용할 수 있게 도와주는 coro()
유틸리티는 Generator 인터페이스(.next()
)를 함수 호출 인터페이스로 변경해주는 어댑터이다.
비교
함수로 구현한 이벤트 핸들러는 클릭 정보를 저장해 둘input
이라는 상태 변수를 핸들러 내부에 둘 수가 없다. 그래서 함수 외부(클로져)에 두었다. Java 같으면 객체 필드로 옮겨야 할 것이다. 이렇게 상태 변수를 외부로 빼고 나면 핸들러 함수는 어떤 식으로든 직접 상태 머신을 구현해야 한다.
반면 코루틴으로 구현한 핸들러는 input
변수가 로컬로 선언되었다. 이벤트 객체는 yield
로 하나씩 가져오는데, 마치 C로 처음 짜보는 야구 게임처럼 루프를 돌면서 클릭 이벤트 객체를 “읽어”들인다. input
을 사용하기 전에 초기화하는 것도 자연스럽다. (함수 구현에서는 뒤에 한 번 더 초기화해줘야 한다.)
여기서 구현해본 노크코드의 경우는 input
하나로 상태를 나타낼 수 있었지만 노크 코드의 기능을 확장하여 탭 간 시간 간격이 어느 정도 일치해야 통과한다고 하면 좀더 복잡해지지 않을까. (참고 : Knock!Knock! 코루틴 #2)
곁다리: Async 코루틴
성공/실패 메시지를 보여주는 작은 애니메이션에도 코루틴을 활용할 수 있다.
다음 글: Stackful/Stackless 코루틴