我想使用asyncio
实现以下目标:
# Each iteration of this loop MUST last only 1 second
while True:
# Make an async request
sleep(1)
但是,我所看到的唯一示例使用的是
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_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())
它将每秒钟在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())
需要注意的另一件事是,您每次都在单独的线程中运行请求。它可以工作,但是有点可笑。您应该使用真正的异步HTTP客户端,例如aiohttp。
关于python - 如何发出请求而不阻塞(使用asyncio)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46693656/