结合像Promise.all这样的等待

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结合像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()

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

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

答案

相当于使用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()

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

因为当你在awaitseq每个项目,你阻止该协程。所以从本质上讲,你有同步代码伪装成async。如果你真的想,你可以使用asyncio.waitloop.create_task实现自己的asyncio.ensure_future版本。

编辑

正如安德鲁提到的,你也可以使用asyncio.gather

另一答案

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

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

以上是关于结合像Promise.all这样的等待的主要内容,如果未能解决你的问题,请参考以下文章

Promise.all() 不等待异步进程

使用 Promise.all 避免等待每个单独的循环迭代

Promise.all 和 .map 函数的异步/等待无法按预期工作

Promise.all() 与等待

await 与 Promise.all 结合使用

await 与 Promise.all 结合使用