首页 > 解决方案 > 在生成器函数中返回时未执行带有异步任务的 Python 3

问题描述

第一个示例不起作用,我尝试发出异步任务,但不关心这种情况下的响应,输出为空:

from typing import Iterable
import asyncio

async def example_task():
    print('example_task')

def emit() -> Iterable:
    event_loop = asyncio.get_event_loop()
    yield event_loop.create_task(example_task())

async def main():
    emit()
    await asyncio.sleep(0.5) # wait some time so the task can run

asyncio.run(main())

当我添加next(emit())到实际“读取”产生的任务时,输出工作,并且在下一个示例中,当我首先将所有任务放入列表时它工作:

from typing import Iterable
import asyncio

async def example_task():
    print('example_task')

def emit() -> Iterable:
    event_loop = asyncio.get_event_loop()
    return iter([event_loop.create_task(example_task())]) 

async def main():
    emit()
    await asyncio.sleep(0.5) # wait some time so the task can run

asyncio.run(main())

这只是一个简单的例子,最终版本应该能够发出一个“事件”并运行 1..n 个可以返回值但不需要的异步任务。发出的调用者应该能够决定他是在某个时候等待结果还是像示例中那样忽略它。

有什么方法可以使用生成器/产量来做到这一点,或者是将所有任务存储在列表中并在此之后返回迭代器的唯一可能方法?

标签: python-3.xpython-asyncio

解决方案


问题是您正在返回带有第一个示例的生成器,其中第二个示例具有需要执行的任务对象。

您的第一个示例的修改版本将类似于

async def main():
    next(emit())
    await asyncio.sleep(0.5) # wait some time so the task can run

或者

async def main():
    for task in emit():
        await task
        await asyncio.sleep(0.5) # wait some time so the task can run

希望这能解释在创建任务时使用生成器和迭代器之间的区别。


推荐阅读