我正在尝试编写一个不和谐机器人,用来从http休息调用中获取的数据更新用户 .
由于discord.py使用asyncio,我想我会尝试通过这种方法 .
async def my_background_task():
print("starting BG task")
await client.wait_until_ready()
while not client.is_closed:
requests.get(getMyUrl()).json()["dict_element"]
#do more stuff
client.loop.create_task(my_background_task())
client.run("api key goes here")
使用同步“请求”库可以直截了当 . 但是我可以运行它几个小时直到它崩溃 . 我假设因为'请求'未能完成无限循环 .
async def fetch(session, url):
async with session.get(url) as resp:
print(resp.status)
return await resp
async def fetch_url(loop, url):
async with aiohttp.ClientSession(loop=loop) as session:
await fetch(session, url)
async def my_method(url):
loop = asyncio.get_event_loop()
return loop.run_until_complete(fetch_url(loop,url))
async def my_background_task():
print("starting BG task")
await client.wait_until_ready()
while not client.is_closed:
await my_method.("www.theinternet.com/restcall").json()["dict_element"]
#do more stuff
所以我现在尝试使用aiohttp,但在此循环中遇到异步循环问题 .
我还没有找到关于如何解决这个问题的正确解释 . 我是python和异步函数的新手 .
2 回答
如果没有您从aiohttp版本获得的错误,很难猜到 . 但乍一看,我会说:
无需将事件循环显式传递给
ClientSession
,它会自动选择当前事件循环,因此您只需调用ClientSession()
fetch
函数不应await resp
.resp
不是那里的协程 . 您可能想return await resp.json()
(并删除my_background_task
中的额外.json()
)在
my_method
中,您已经在协程中运行,如async def
所示 . 所以要调用另一个协同程序,你应该await
-ing它,而不是创建一个新的事件循环并在新的循环中运行它 .在
my_background_task
中,您正在等待一些没有任何意义的事情:检查await的操作员优先级,您在协程上调用.__getitem__
,然后等待__getitem__
的结果,这与您想要的相反 .仍然在那一行,你不能在响应关闭后尝试读取响应的json主体(响应在你退出
async with
时立即关闭,即只要fetch
方法完成) .最后,您不应该在每个循环中重新创建ClientSession . 这是存在的,因此它可以在请求之间共享,因此您应该在
my_background_task
中创建一次并使用它我通过另一个后台任务来解决这个问题,该任务将http响应保持为全局变量并自行更新 .
我不确定这是不是我应该这样做的方式,但这就是让我脱离泡菜的原因 .