asyncio
については非常に特別なことが1つあります。これが非同期コールバックと同期コールバックの違いです。いくつかの例を紹介しましょう。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)
これらの2つの例は、機能的に非常に似ていますが、彼らは両方の異なった方法でそれをやっているように見えます。最初の例では、何らかのアクションで通知を受けたい場合は、同期関数(EchoServer.connection_made
)を指定します。ただし、2番目の例では、何らかのアクションで通知を受けたい場合は、非同期コールバック関数(simple
)を定義する必要があります。
この2つのタイプのコールバックの違いは何ですか。私は、通常の関数と非同期関数の違いを理解していますが、私はコールバックの違いについて私の頭を包むことはできません。たとえば、aiohttp
のような非同期APIを作成したいと思ったら、何かをしてコールバックを呼び出す関数を用意していますが、引数として渡す非同期関数を要求する必要があるかどうかはどのように決定しますかまたは単に定期的な同期のもの? 、データベースへのアクセスだけ定期的に同期メソッドを呼び出す必要がありProtocol.data_received()
でなど
をHTTPリクエストを行います。
しかし、私がイベントループへの参照を保持している場合でも、私は同期化された '' Protocol.data_received() ''でも非同期メソッドを呼び出すことができます。 –
'Protocol.data_received()'で 'await'を使うことはできませんが、shoutdはタスクを作り、どこかのタスクの終了を待ちます。 –
したがって、同期コールバックまたは非同期コールバックを必要とする関数を公開するかどうかは、APIの観点からは基本的に無関係です。あるいは、asyncioの開発者が厳密に '' Protocol''クラスで同期コールバックを必要とする特定の要因がありましたか? –