在异步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()
但它会按顺序执行我的任务。
等待多个等待的最简单方法是什么? 为什么我的方法不起作用?
答案 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。如果你真的想要,你可以使用await
或seq
来实现自己的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
,而不是设计出具有副作用的方法。