结合像Promise.all这样的等待

时间:2015-12-20 02:07:17

标签: python python-3.x async-await future python-asyncio

在异步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()

但它会按顺序执行我的任务。

等待多个等待的最简单方法是什么? 为什么我的方法不起作用?

3 个答案:

答案 0 :(得分:38)

相当于使用asyncio.wait

public class Main {
    public static void main(String[] args) {
        BooleanVector vector = new BooleanVector(5);
        vector.printVector();
        System.out.println("Invert1");
        vector.invert1();
        vector.printVector();
        System.out.println("Invert2");
        vector.invert2();
        vector.printVector();
        System.out.println("Invert1");
        vector.invert1();
        vector.printVector();

    }

}
  

为什么我的方法不起作用?

因为当您[true, true, false, true, false] Invert1 [false, false, true, false, true] Invert2 [false, false, true, false, true] Invert1 [true, true, false, true, false] 中的每个项目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() 时,您会阻止该协程。所以从本质上讲,你有同步代码伪装成async。如果你真的想要,你可以使用awaitseq来实现自己的asyncio.wait版本。

修改

正如安德鲁所说,你也可以使用asyncio.gather

答案 1 :(得分:2)

我注意到asyncio.gather()可能是一种更好的等待方式,而不是asyncio.wait()如果我们想要有序的结果。

正如文档所示,asyncio.gather()方法的结果值的顺序与aws中的waitables的顺序相对应。但是,asyncio.wait()中结果值的顺序不会做相同的事情。您可以对其进行测试。

答案 2 :(得分:2)

https://docs.python.org/3/library/asyncio-task.html#asyncio.gather

asyncio.gather()将返回每个异步函数调用的输出列表。

import asyncio

async def bar(i):
    print('started', i)
    await asyncio.sleep(1)
    print('finished', i)
    return i

async def main():
    values = await asyncio.gather(*[bar(i) for i in range(10)])
    print(values)

asyncio.run(main())

此方法collect可以为并发作业使用任意数量的args而不是列表,因此我们将其解压缩。

在我的示例中,通常需要这个中间值values,而不是设计出具有副作用的方法。