结合像 Promise.all 这样的等待 [英] Combine awaitables like Promise.all

查看:20
本文介绍了结合像 Promise.all 这样的等待的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Why doesn't my approach work?

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 这样的等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆