【问题标题】:How to create an asyncio task that return value?如何创建一个返回值的异步任务?
【发布时间】:2021-04-06 12:27:16
【问题描述】:

我正在研究如何在asyncio 中返回一个列表[] 我知道asyncio.gather 可以帮助我,但是我现在很困惑有很多方法。 如何从 main() 返回值?谢谢

async def wait_until(dt):
    # sleep until the specified datetime
    now = datetime.now()
    await asyncio.sleep((dt - now).total_seconds())

async def run_at(dt, coro):
    await wait_until(dt)
    return await coro

async def main():
    test=[]
    async for message in client.iter_messages(channel):
        test.append(message)
        return test


loop = asyncio.get_event_loop()
loop.create_task(run_at(datetime(2020, 12, 29, 19, 17),main()))
loop.run_until_complete(asyncio.gather(*[main()]))
# How to get test[] or How to pass it to another task?
loop.run_forever()

【问题讨论】:

  • 我将使用全局变量,但我确信有更好的方法来做到这一点。另外,您是否知道在第一个循环后返回test[]

标签: python async-await return python-asyncio telethon


【解决方案1】:

来自asyncio.gather 文档:

如果所有可等待对象都成功完成,则结果是返回值的聚合列表。结果值的顺序对应于aws中的awaitables的顺序。

来自asyncio.loop.run_until_complete 文档:

返回 Future 的结果或引发它的异常。

所以gather 是一个async def,它返回所有传递的结果,run_until_complete 运行循环“转换”awaitable 为结果。基本上,返回值都是通过的:

results = loop.run_until_complete(asyncio.gather(*[main()]))
tests = results[0]

请注意,gather 仅包含一项是多余的,因为它等同于仅使用一项:

tests = loop.run_until_complete(main())

如果您想在不使用全局变量的情况下传达两个独立的任务,您可能希望使用asyncio.Queue,并将相同的队列实例作为输入参数提供给两个async def。一个将put“消息”,另一个将get他们。

您可以将其与waitgathercreate_task 等结合使用,几乎可以满足您的所有需求。

【讨论】:

    猜你喜欢
    • 2017-12-16
    • 2013-03-22
    • 1970-01-01
    • 2015-10-30
    • 1970-01-01
    • 1970-01-01
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多