在异步JavaScript中,很容易并行运行任务并等待所有这些任务完成Promise.all
:
async function bar(i) { console.log('started', i); await delay(1000); console.log('finished', i); } async function foo() { await Promise.all([bar(1), bar(2)]); } // This works too: async function my_all(promises) { for (let p of promises) await p; } async function foo() { await my_all([bar(1), bar(2), bar(3)]); }
我试图在python中重写后者:
import asyncio async def bar(i): print('started', i) await asyncio.sleep(1) print('finished', i) async def aio_all(seq): for f in seq: await f async def main(): await aio_all([bar(i) for i in range(10)]) loop = asyncio.get_event_loop() loop.run_until_complete(main()) loop.close()
但它按顺序执行我的任务.
等待多个等待的最简单方法是什么?为什么我的方法不起作用?
相当于使用asyncio.wait
:
import asyncio async def bar(i): print('started', i) await asyncio.sleep(1) print('finished', i) async def main(): await asyncio.wait([bar(i) for i in range(10)]) loop = asyncio.get_event_loop() loop.run_until_complete(main()) loop.close()
为什么我的方法不起作用?
因为当你await
每个项目进入时seq
,你会阻止该协同程序.所以从本质上讲,你有同步代码伪装成async.如果你真的想,你可以实现自己的asyncio.wait
使用loop.create_task
或版本asyncio.ensure_future
.
编辑
正如安德鲁所说,你也可以使用asyncio.gather
.
我注意到,如果我们想要有序的结果,那么asyncio.gather()可能是比asyncio.wait()更好的等待方式。
如文档所示,asyncio.gather()方法的结果值的顺序与aws中的awaitables的顺序相对应。但是,asyncio.wait()中结果值的顺序不会做相同的事情,您可以对其进行测试。