<p>您使用<code>async def</code>使<code>faire_toutes_les_requetes_sans_bloquer</code>成为一个可等待的</em>函数,一个协程。</p>
<p>当您调用一个可等待的函数时,您将创建一个新的协程对象。函数中的代码在您等待函数或将其作为任务运行之前不会运行:</p>
<pre><code>>>> async def foo():
... print("Running the foo coroutine")
...
>>> foo()
<coroutine object foo at 0x10b186348>
>>> import asyncio
>>> asyncio.run(foo())
Running the foo coroutine
</code></pre>
<p>您希望保持函数<em>同步</em>,因为在该函数内部之前不会启动循环:</p>
<pre><code>def faire_toutes_les_requetes_sans_bloquer():
loop = asyncio.get_event_loop()
# ...
loop.close()
print("Fin de la boucle !")
</code></pre>
<p>但是,您还试图使用一个<code>aiophttp.ClientSession()</code>对象,这是一个异步上下文管理器,您需要将它与<code>async with</code>一起使用,而不仅仅是<code>with</code>,因此必须在一个可等待的任务旁边运行。如果使用<code>with</code>而不是<code>async with</code>,将引发<code>TypeError("Use async with instead")</code>异常。</p>
<p>这意味着您需要将<code>loop.run_until_complete()</code>函数的<code>faire_toutes_les_requetes_sans_bloquer()</code>调用^{<em>移到^{</em>之外,这样您就可以将其作为主任务来运行;您可以直接调用并等待<code>asycio.gather()</code>:</p>
<pre><code>async def faire_toutes_les_requetes_sans_bloquer():
async with aiohttp.ClientSession() as session:
futures = [requete_sans_bloquer(x, session) for x in range(10)]
await asyncio.gather(*futures)
print("Fin de la boucle !")
print("Non bloquant : ")
start = datetime.datetime.now()
loop.run(faire_toutes_les_requetes_sans_bloquer())
exec_time = (datetime.datetime.now() - start).seconds
print(f"Pour faire 10 requêtes, ça prend {exec_time}s\n")
</code></pre>
<p>我使用新的<a href="https://docs.python.org/3/library/asyncio-task.html#asyncio.run" rel="noreferrer">^{<cd12>} function</a>(Python 3.7及更高版本)来运行单个主任务。这将为顶级协程创建一个专用循环并运行它直到完成。</p>
<p>接下来,需要移动<code>await resp.json()</code>表达式上的结束<code>)</code>括号:</p>
<pre><code>uid = (await response.json())['uuid']
</code></pre>
<p>您要访问<code>await</code>结果上的<code>'uuid'</code>键,而不是<code>response.json()</code>生成的协程。</p>
<p>通过这些更改,您的代码可以工作,但异步版本在次秒时间内完成;您可能需要打印微秒:</p>
<pre><code>exec_time = (datetime.datetime.now() - start).total_seconds()
print(f"Pour faire 10 requêtes, ça prend {exec_time:.3f}s\n")
</code></pre>
<p>在我的机器上,同步的<code>requests</code>代码在大约4-5秒内完成,而asycio代码在不到0.5秒的时间内完成。</p>