问题描述
在异步 JavaScript 中,使用 Promise.all
很容易并行运行任务并等待所有任务完成:
async function bar(i) {console.log('开始', i);等待延迟(1000);console.log('完成', i);}异步函数 foo() {等待 Promise.all([bar(1), bar(2)]);}//这也有效:异步函数 my_all(promises) {for (let p of promises) await p;}异步函数 foo() {等待 my_all([bar(1), bar(2), bar(3)]);}
我试图用python重写后者:
导入异步异步定义栏(i):打印('开始',我)等待 asyncio.sleep(1)打印('完成',我)异步定义 aio_all(seq):对于 seq 中的 f:等待 f异步定义主():await aio_all([bar(i) for i in range(10)])loop = asyncio.get_event_loop()loop.run_until_complete(main())循环关闭()
但它按顺序执行我的任务.
等待多个可等待对象的最简单方法是什么?为什么我的方法不起作用?
相当于使用 asyncio.gather
:
导入异步异步定义栏(i):打印('开始',我)等待 asyncio.sleep(1)打印('完成',我)异步定义主():await asyncio.gather(*[bar(i) for i in range(10)])loop = asyncio.get_event_loop()loop.run_until_complete(main())循环关闭()
为什么我的方法不起作用?
因为当你await
seq
中的每一项时,你就会阻塞那个协程.所以本质上,你有伪装成异步的同步代码.如果你真的想要,你可以使用 loop.create_task
或 asyncio.ensure_future
实现你自己的 asyncio.gather
版本代码>.
编辑
原始答案使用了较低级别的 asyncio.wait
.
In asynchronous JavaScript, it is easy to run tasks in parallel and wait for all of them to complete using 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)]);
}
I tried to rewrite the latter in 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()
But it executes my tasks sequentially.
What is the simplest way to await multiple awaitables?Why doesn't my approach work?
The equivalent would be using asyncio.gather
:
import asyncio
async def bar(i):
print('started', i)
await asyncio.sleep(1)
print('finished', i)
async def main():
await asyncio.gather(*[bar(i) for i in range(10)])
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
Because when you await
each item in seq
, you block that coroutine. So in essence, you have synchronous code masquerading as async. If you really wanted to, you could implement your own version of asyncio.gather
using loop.create_task
or asyncio.ensure_future
.
EDIT
The original answer used the lower-level asyncio.wait
.
这篇关于结合像 Promise.all 这样的等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!