yield 와 callback
yield 와 callback 은 많이 비슷하다. 실제로 작성하는 code 의 flow 는 많이 닮았다.하지만, yield 는 직접 control(code 가 수행되는 순서로 보자) 을 제어할 수 있는 keyword 이기 때문에 이녀석이 좀 더 큰 범위에 있다고 보면 되겠다. 쉽게 이야기 하면, yield 로 callback 처럼 event 가 끝난 후에 다시 호출이 되는 구조의 code 를 구성할 수 있다.
callback 이 여러개인 경우
만약에 많은 callback 으로 표현해야 하는 경우, 예를 들면, network 에 대한 작업이 연속적으로 5번 일어나야 한다고 하면, callback 을 5번 이나 작성하게 되는데, 이러면 code 의 가독성이 떨어질 가능성이 많아진다.하지만, yield 를 사용하면, 연속적으로 하나의 code 를 작성할 수 있어서 가독성도 좋고, 명확하게 하는 일을 보여줄 수 있다.
try/catch 를 한곳에
callback 에 비해 yield 를 이용할 때 또 하나의 장점은 같은 일을 하는 녀석을 하나의 code 처럼 한 function 안에 담을 수 있다. 이로 인해서 try/catch 를 이용할 때도 같은 종류의 exception 을 한 곳에서 try/catch 로 묶어놓을 수 있다.[ref. 1]Reading a code
request 가 끝나면 doSomething() 을 해라requests.get(callback=function(){ doSomething() })
http_request() 가 끝난 후 doSomething() 을 하겠다. http_request() 가 끝날동안 control 을 일단 양보(yield) 하마, 일단 다른일을 해라, 그 일이 끝나면 내가 doSomething() 을 하겠다.
yield http_request() doSomething()
callback 을 yield 로 변경
ref. 3에 보면 callback 의 구조를 yield 를 사용하는 구조로 변경한 경우가 있다.(callback 을 yield 로 변경하는 법을 이야기하는 것은 아니다. 이 부분은 tornamdo.gen.coroutine 내부를 살펴보자.)이 code 로 callback 과 yield 의 flow 의 차이를 느껴볼 수 있다.
class AsyncHandler(RequestHandler): @asynchronous def get(self): http_client = AsyncHTTPClient() http_client.fetch("http://example.com", callback=self.on_fetch) def on_fetch(self, response): do_something_with_response(response) self.render("template.html")
class GenAsyncHandler(RequestHandler): @gen.coroutine def get(self): http_client = AsyncHTTPClient() response = yield http_client.fetch("http://example.com") do_something_with_response(response) self.render("template.html")
댓글 없음:
댓글 쓰기