结合像 Promise.all 这样的可等待对象

新手上路,请多包涵

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

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

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

原文由 Tamas Hegedus 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 655
2 个回答

等同于使用 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()

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

因为当你 await 中的每一项时 seq ,你阻止了协程。所以本质上,你有伪装成异步的同步代码。如果您真的 _想要_,您可以使用 loop.create_taskasyncio.ensure_future asyncio.gather

编辑

原始答案使用了较低级别的 asyncio.wait

原文由 Jashandeep Sohi 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

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

原文由 Stackoverflow 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题