Dot*_*otl 6 python python-3.x python-requests python-asyncio
我想实现以下使用asyncio:
# Each iteration of this loop MUST last only 1 second
while True:
# Make an async request
sleep(1)
Run Code Online (Sandbox Code Playgroud)
然而,我见过的唯一例子使用了一些变体
async def my_func():
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, requests.get, 'http://www.google.com')
loop = asyncio.get_event_loop()
loop.run_until_complete(my_func())
Run Code Online (Sandbox Code Playgroud)
但是run_until_complete是阻塞!run_until_complete在我的while循环的每次迭代中使用会导致循环阻塞。
我花了最后几个小时试图弄清楚如何正确运行非阻塞任务(用 定义async def)但没有成功。我一定遗漏了一些明显的东西,因为像这样简单的东西肯定应该很简单。我怎样才能实现我所描述的?
run_until_complete运行主事件循环。可以这么说,它不是“阻塞”,它只是运行事件循环,直到作为参数传递的协程返回。它必须挂起,否则程序将停止或被下一条指令阻止。
很难说出你愿意实现什么,但是这段代码实际上做了一些事情:
async def my_func():
loop = asyncio.get_event_loop()
while True:
res = await loop.run_in_executor(None, requests.get, 'http://www.google.com')
print(res)
await asyncio.sleep(1)
loop = asyncio.get_event_loop()
loop.run_until_complete(my_func())
Run Code Online (Sandbox Code Playgroud)
它会每秒在 Google 主页上执行一次 GET 请求,弹出一个新线程来执行每个请求。您可以通过虚拟并行运行多个请求来说服自己它实际上是非阻塞的:
async def entrypoint():
await asyncio.wait([
get('https://www.google.com'),
get('https://www.stackoverflow.com'),
])
async def get(url):
loop = asyncio.get_event_loop()
while True:
res = await loop.run_in_executor(None, requests.get, url)
print(url, res)
await asyncio.sleep(1)
loop = asyncio.get_event_loop()
loop.run_until_complete(entrypoint())
Run Code Online (Sandbox Code Playgroud)
另一件需要注意的事情是您每次都在单独的线程中运行请求。它确实有效,但有点像黑客。您应该使用真正的异步 HTTP 客户端,例如aiohttp。
| 归档时间: |
|
| 查看次数: |
4249 次 |
| 最近记录: |