如何创建 return 值的异步任务?

How to create an asyncio task that return value?

我正在研究如何 return 在 asyncio 中创建一个列表[] 我知道 asyncio.gather 可以帮助我,但我现在对很多方法感到困惑。 我如何 return 来自 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()

来自 asyncio.gather 文档:

If all awaitables are completed successfully, the result is an aggregate list of returned values. The order of result values corresponds to the order of awaitables in aws.

来自 asyncio.loop.run_until_complete 文档:

Return the Future’s result or raise its exception.

所以 gather 是一个 async def,return 所有结果都通过了,并且 run_until_complete 运行循环将可等待对象“转换”为结果。基本上,return 值通过:

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

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

tests = loop.run_until_complete(main())

如果你想在不使用全局变量的情况下传达两个独立的任务,你可能想使用 asyncio.Queue, and give the same queue instance to both async def as input parameters. One will put "messages", and the other will get 它们。

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