Powiedzmy, że mamy funkcję fikcyjną:
async def foo(arg):
result = await some_remote_call(arg)
return result.upper()
Jaka jest różnica pomiędzy:
import asyncio
coros = []
for i in range(5):
coros.append(foo(i))
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(coros))
I:
import asyncio
futures = []
for i in range(5):
futures.append(asyncio.ensure_future(foo(i)))
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(futures))
Uwaga : przykład zwraca wynik, ale nie jest to główny temat pytania. Gdy wartość zwracana ma znaczenie, użyj gather()
zamiast wait()
.
Niezależnie od wartości zwracanej, szukam jasności ensure_future()
. wait(coros)
i wait(futures)
oba obsługują programy, więc kiedy i dlaczego powinien być zawinięty w coroutine ensure_future
?
Zasadniczo, jaki jest właściwy sposób (tm), aby wykonać kilka operacji nieblokujących przy użyciu języka Python 3.5 async
?
Aby uzyskać dodatkowe środki, co jeśli chcę grupować połączenia? Na przykład muszę dzwonić some_remote_call(...)
1000 razy, ale nie chcę niszczyć serwera WWW / bazy danych / itp. Przy 1000 jednoczesnych połączeniach. Można to zrobić za pomocą wątku lub puli procesów, ale czy istnieje sposób, aby to zrobić asyncio
?
Aktualizacja 2020 (Python 3.7+) : Nie używaj tych fragmentów. Zamiast tego użyj:
import asyncio
async def do_something_async():
tasks = []
for i in range(5):
tasks.append(asyncio.create_task(foo(i)))
await asyncio.gather(*tasks)
def do_something():
asyncio.run(do_something_async)
Rozważ także użycie Trio , solidnej alternatywy innej firmy dla asyncio.
ensure_future()
? A jeśli potrzebuję wyniku, czy nie mogę po prostu użyćrun_until_complete(gather(coros))
?