Admin

python阻止async和await异步传染问题
2018年11月30日 13:55 24 0 0 0

说明

使用协程工具 asyncioaiohttpaiofile 等相关接口时,在异步逻辑中,不可避免的经常使用 await 关键字。于此同时, await 关键字所在的方法也必须是 async 关键字声明的异步方法。例如:

  1. async def req_async():
  2. """ request with aiohttp """
  3. url = '127.0.0.1'
  4. content = 'hello'
  5. async with aiohttp.ClientSession() as session:
  6. async with session.post(url=url, data=content) as resp:
  7. if resp.status != 200:
  8. raise Exception(f'request error code: {resp.status}')
  9. return await resp.text()
  10. async def level1_call():
  11. """ do some business """
  12. await reqasync()
  13. async def level0_call():
  14. """ do some business """
  15. await level1_call()

这样,就导致了调用过程的向上传染,如果最顶层方法与异步调用兼容就会出现问题,例如:@pyqtSlot() 装饰的槽函数,如果函数是 async 关键字定义的异步函数,就不能正确触发。

解决方案

异步调用

  1. @pyqtSlot()
  2. def button_clicked():
  3. loop = asyncio.get_event_loop()
  4. asyncio.ensure_future(req_async(), loop=loop)

阻塞调用

  1. @pyqtSlot()
  2. def button_clicked():
  3. loop = asyncio.get_event_loop()
  4. svc = TTSService()
  5. tasks = [svc.req_async()]
  6. loop.run_until_complete(asyncio.wait(tasks))
发布内容,请遵守相关法律法规。
评论