2016-08-29 3 views
3

asyncio에 대해 아주 특별한 점이 있습니다. 이해할 수없는 부분이 있습니다. 이것이 비동기 콜백과 동기 콜백의 차이점입니다. 몇 가지 예를 소개하겠습니다.asyncio 이해 : 비동기 대 동기 콜백

Asyncio TCP 예 :

class EchoServer(asyncio.Protocol): 

def connection_made(self, transport): 
    print('connection made') 

def data_received(self, data): 
    print('data received: ', data.decode()) 

def eof_received(self): 
    pass 

def connection_lost(self, exc): 
    print('connection lost:', exc) 

Aiohttp 예 :

async def simple(request): 
    return Response(text="Simple answer") 

async def init(loop): 
    app = Application(loop=loop) 
    app.router.add_get('/simple', simple) 
    return app 

loop = asyncio.get_event_loop() 
app = loop.run_until_complete(init(loop)) 
run_app(app, loop=loop) 

그 두 예는 기능면에서 매우 유사하지만 그들은 모두 서로 다른 방법으로 그 일을 할 것 같다. 첫 번째 예에서 일부 작업에 대해 알리려면 동기 함수 (EchoServer.connection_made)를 지정합니다. 그러나 두 번째 예에서 일부 작업에 대한 알림을 받으려면 비동기 콜백 함수 (simple)를 정의해야합니다.

이 두 유형의 콜백의 차이점은 무엇입니까? 일반 함수와 비동기 함수의 차이점을 이해하지만 콜백 차이를 감안하여 머리를 감쌀 수는 없습니다. 예를 들어, aiohttp과 같은 비동기 API를 작성하고 싶다면, 무언가를 수행하고 콜백을 호출하는 함수가 있어야합니다. 비동기 함수를 인수로 전달해야하는지 결정해야합니다. 아니면 그냥 정기적 인 동기식 하나? , 데이터베이스에 대한 액세스 권한 만 일반 동기 메소드를 호출한다 Protocol.data_received()에서 등

을 HTTP 요청을합니다

답변

1

aiohttp 예에서는 simple 웹 핸들러에서 비동기 호출을 할 수 있습니다.

콜백이 디자인에 의해 동기로되어 있습니다

Protocol UPD. 이들은 동기화와 비동기 간의 매우 낮은 레벨의 브리지입니다. 비동기 코드를 호출 할 수 있지만 실제로 까다로운 코딩이 필요합니다. 등 소켓 사용자 수준 asyncio API는 스트림 있습니다 https://docs.python.org/3/library/asyncio-stream.html

당신이 콜백이 비동기 코드를 호출하고 싶지는 않을 이유가 확실 100 %가 아니라면 자신의 콜백 시스템이 가능성이 비동기 콜백이 필요합니다 소개합니다.

일반 함수 (def)와 coroutines (async def)의 서명이 다릅니다. 필요한 서명을 변경하는 것은 어렵습니다. 특히 코드가 라이브러리로 게시되고 콜백의 모든 사용자를 제어 할 수없는 경우 특히 그렇습니다.

P.

모든 공개 API 메소드에서도 마찬가지입니다.

내 라이브러리를 개발하는 동안 배운 가장 어려운 교훈은 다음과 같습니다. .close() 방법 은 처음에는 동시 기능 만 호출합니다. socket.close().

그러나 나중에는 정상적인 작업 종료를 기다리는 정상적인 종료를 추가하는 것이 좋습니다.사용자가 obj.close() 같은 API를 호출 한 경우

지금은 await obj.close()를 사용해야하지만 이전 버전과 호환되지 않는 변화입니다!

+0

그러나 이벤트 루프에 대한 참조를 유지한다면 동기식 "Protocol.data_received()"에서도 비동기 메서드를 호출 할 수 있습니다. –

+0

'Protocol.data_received()'에서'await'을 사용할 수 없지만 shoutd는 작업을 만들고 어딘가에 작업 완료를 기다립니다. –

+0

그래서 API의 관점에서 동기 콜백 또는 비동기 콜백이 필요한 함수를 노출하는지 여부는 기본적으로 관련이 없습니다. 아니면 asyncio의 개발자가''Protocol'' 클래스에서 동기 콜백을 엄격하게 요구하도록 만든 특정 요인이 있습니까? –