如何将多个值从异步函数返回到同步上下文?

时间:2019-06-30 12:08:25

标签: python python-asyncio python-3.7 asyncio

我需要从异步调用中收集结果并将它们返回给普通函数-桥接异步和同步代码部分会使我感到困惑。

首先尝试使用难看的inout参数。

import asyncio
import aiohttp

async def one_call(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            txt = await response.text()
            return txt[0:20]


async def do_all(result_inout):
    urls = ["https://cnn.com", "https://nyt.com", "http://reuters.com"]
    out = await asyncio.gather(*[one_call(url) for url in urls])
    result_inout += out

if __name__ == "__main__":
    result_inout = []
    asyncio.run(do_all(result_inout))

    print(result_inout)

第二次尝试,但直接使用事件循环,对于应用程序代码,该事件循环为discouraged

if __name__ == "__main__":
    # same imports, same one_call, same urls
    loop = asyncio.get_event_loop()

    aggregate_future = asyncio.gather(*[one_call(url) for url in urls])
    results = loop.run_until_complete(aggregate_future)
    loop.close()

    print(results) 

最好的方法是什么?

1 个答案:

答案 0 :(得分:2)

不需要result_inout,您只需使用out = asyncio.run(do_all())即可获得return res的{​​{1}}。

do_all

输出将为import asyncio import aiohttp async def one_call(url): await asyncio.sleep(2) return 0 async def do_all(): urls = ["https://cnn.com", "https://nyt.com", "http://reuters.com"] out = await asyncio.gather(*[one_call(url) for url in urls]) return out if __name__ == "__main__": out = asyncio.run(do_all()) print(out)