現在、多くのHTTPリクエストを順番に実行して結果を得る非効率な同期ジェネレータがあります。 asyncio
とaiohttp
を使用してリクエストを並列化し、このジェネレータを高速化したいのですが、通常のジェネレータ(PEP 525 async generatorではなく)にしておきたいので、非同期コードで呼び出す必要はありません変更される。どのようにしてそのような発電機を作ることができますか?コルーチンが終了するときにコルーチン結果を生成するジェネレータを作成
1
A
答えて
4
asyncio.as_completed()
は、コルーチンまたは先物の繰返しを受け取り、入力先物が完了する順序で先物の繰返しを返します。 通常、あなたはその結果をループをいただきたいとawait
async
関数内からメンバーを...
import asyncio
async def first():
await asyncio.sleep(5)
return 'first'
async def second():
await asyncio.sleep(1)
return 'second'
async def third():
await asyncio.sleep(3)
return 'third'
async def main():
for future in asyncio.as_completed([first(), second(), third()]):
print(await future)
loop = asyncio.get_event_loop()
# Prints 'second', then 'third', then 'first'
loop.run_until_complete(main())
を...しかし、この質問の目的のために、私たちが望むことは降伏することができることです通常の同期コードは、async
関数がフードの下で使用されていることを知らずにそれらを消費することができるように、通常のジェネレータからの結果です。私たちは、このように
import asyncio
async def first():
await asyncio.sleep(5)
return 'first'
async def second():
await asyncio.sleep(1)
return 'second'
async def third():
await asyncio.sleep(3)
return 'third'
def ordinary_generator():
loop = asyncio.get_event_loop()
for future in asyncio.as_completed([first(), second(), third()]):
yield loop.run_until_complete(future)
# Prints 'second', then 'third', then 'first'
for element in ordinary_generator():
print(element)
は、我々は必要としない方法で非非同期の土地に私たちの非同期コードを公開しました...私たちの
as_completed
呼び出しによって得られた先物
loop.run_until_complete()
を呼び出すことによってそれを行うことができますファンクションを
async
と定義したり、
ordinary_generator
がフードの下で
asyncio
を使用していることを知ることさえできます。
、いくつかの状況では、より多くの柔軟性を提供していますordinary_generator()
の代替実装として、我々は代わりにas_completed()
をループのFIRST_COMPLETED
フラグとasyncio.wait()
を繰り返し呼び出すことができます。
import concurrent.futures
def ordinary_generator():
loop = asyncio.get_event_loop()
pending = [first(), second(), third()]
while pending:
done, pending = loop.run_until_complete(
asyncio.wait(
pending,
return_when=concurrent.futures.FIRST_COMPLETED
)
)
for job in done:
yield job.result()
このアプローチ、pending
ジョブのリストを維持し、ジョブを即座にpending
リストに追加することができるという利点があります。これは、非同期ジョブが、キューにアクセスする各ページのすべてのリンクに続くWebスパイダーのように、予想外の数のジョブをキューに追加できるような場合に便利です。
関連する問題
- 1. コルーチンが終了するのを待つ
- 2. コルーチンとコンティニュエーションとジェネレータ
- 3. ループ終了前のPythonコルーチンからの結果の収集
- 4. Python `with`コンテキストとジェネレータ/コルーチン/タスク
- 5. 非同期コルーチンが終了していないようです
- 6. C++/gcc/linuxの継続/コルーチン/ジェネレータ
- 7. C++コルーチン/ Visual Studio:ジェネレータは、代わりに値を生成する関数をどのように呼び出すことができますか?
- 8. 条件が偽であるときにコルーチンから別のコルーチンに変更する方法
- 9. 非対称コルーチンと対称コルーチンの違いは何ですか?
- 10. PythonのコルーチンはLuaのコルーチンとどう違うのですか?
- 11. CompletableFutureとListenableFutureのコルーチン作成者に違いがあるのはなぜですか? Kotlinのコルーチンのソースを調べる
- 12. 同じ結果を生成するメソッドを作成する
- 13. CPythonでジェネレータとコルーチンがどのように実装されていますか?
- 14. スレッドセーフなコルーチンとasio
- 15. コルーチンからPythonのコルーチンを呼び出す
- 16. 関数C#で移動する前にコルーチンが終了するのを待ちます。
- 17. コルーチンを実行しようとするとエラーが発生する
- 18. リストを生成するジェネレータ
- 19. VS2015 C++コルーチン:promise.get_return_object()戻り値の型とコルーチン戻り値の型
- 20. cmake Xcodeジェネレータが作成できないプロジェクトを作成する
- 21. PureScriptでコルーチンとWebソケットを混ぜる
- 22. Python generatorコルーチン
- 23. Pythonコルーチンのタイムアウト
- 24. コルーチンは、Java
- 25. コルーチンin numba
- 26. Unity C#コルーチンが動作しない
- 27. コルーチンの収量がメインに戻る
- 28. Kotlin:ノンブロッキングI/Oでコルーチンをブロックする
- 29. コルーチンがメインスレッドをブロックしています
- 30. pylint、コルーチン、デコレータと型推論
これらには 'loop.close()'が必要ですか? – Neil