5

I'm figuring out how to return a list[] in asyncio I know asyncio.gather could help me but there are so many ways I'm now confused. How Do I return value from main() ? Thank

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()
  • I'll use a global var, but I'm sure there is a better method to do it. Also, are you aware that you returning `test[]` after the first loop? – TheKill-996 Dec 29 '20 at 23:02

1 Answers1

5

From the asyncio.gather documentation:

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.

From the asyncio.loop.run_until_complete documentation:

Return the Future’s result or raise its exception.

So gather is an async def that returns all the results passed, and run_until_complete runs the loop "converting" the awaitable into the result. Basically, the return values are passed through:

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

Note that gather with just one item is redundant, as it's equivalent to just using that one item:

tests = loop.run_until_complete(main())

If you want to communicate two independent tasks without using global variables, you probably want to use an asyncio.Queue, and give the same queue instance to both async def as input parameters. One will put "messages", and the other will get them.

You can combine this with wait, gather, create_task, etc. to pretty much do everything you need.

Lonami
  • 5,945
  • 2
  • 20
  • 38