以下は、asyncioとaiohttpを使用して複数のWebサイトからホームページをダウンロードするおもちゃの例です。
import asyncio
import aiohttp
sites = [
"http://google.com",
"http://reddit.com",
"http://wikipedia.com",
"http://afpy.org",
"http://httpbin.org",
"http://stackoverflow.com",
"http://reddit.com"
]
async def main(sites):
for site in sites:
download(site)
async def download(site):
response = await client.get(site)
content = await response.read()
print(site, len(content))
loop = asyncio.get_event_loop()
client = aiohttp.ClientSession(loop=loop)
content = loop.run_until_complete(main(sites))
client.close()
実行すると、次のようになります。
RuntimeWarning: coroutine 'download' was never awaited
しかし、私はそれを待ちたくありません。
ツイストで私は行うことができます:
for site in sites:
download(site)
そして、明示的に "yield"しないか、返されたDeferredにコールバックを追加しない場合、ブロックも文句もなしに実行されます。結果にアクセスできませんが、この場合は必要ありません。
JSで私はできる:
site.forEarch(site){
donwload(site)
}
繰り返しになりますが、ブロックすることはなく、私の側から何かを要求することもありません。
私は方法を見つけました:
async def main(sites):
await asyncio.wait([download(site) for site in sites])
だが:
それより良い方法がありますか?
コルーチンをタスクとしてスケジュールするには、 asyncio.ensure_future を使用します。
for site in sites:
coro = download(site)
future = asyncio.ensure_future(coro)
バージョン3.4.4で廃止された関数 asyncio.async を置き換えます。
次に、await
、 asyncio.wait または asyncio.gather を使用して、これらの先物を管理できます。