我目前有如下的for循环
async def process(tasks, num):
count = 0
results = []
for task in tasks:
if count >= num:
break
result = await some_async_task(task)
if result == 'foo':
continue
results.append(result)
count+=1
我想知道我是否可以在这里使用collect或wait_for原语。但是我不确定如何在其中实现这些逻辑?就像..如果count> = num,我不想不必要地等待任务。 如果有20个任务并且num = 4,那么我不想运行所有20个任务。
答案 0 :(得分:2)
您可以按等于所需数量的结果来批量处理任务。如果将此类批处理分配给asyncio.gather()
,它将同时运行它们并保留结果的顺序。例如:
async def process(tasks, num):
results = []
task_iter = iter(tasks)
while len(results) < num:
next_batch = tuple(itertools.islice(task_iter, num - len(results)))
if len(next_batch) == 0:
break
batch_results = await asyncio.gather(*next_batch)
results.extend(r for r in batch_results if r == 'foo')
答案 1 :(得分:1)
使用aiostream library可以轻松实现。这是一个工作示例:
import asyncio
from random import random
from aiostream import stream, pipe
async def some_async_task(i):
await asyncio.sleep(random())
return i if random() < 0.2 else None
async def process(task_args, n):
return await (
stream.iterate(task_args)
| pipe.map(some_async_task, task_limit=n)
| pipe.filter(bool)
| pipe.take(n)
| pipe.list()
)
async def main():
print(await process(task_args=range(100), n=10))
if __name__ == "__main__":
asyncio.run(main())
程序将打印成功的前10个任务的列表:
[1, 8, 16, 18, 19, 37, 42, 43, 45, 47]
还要注意,您可以使用some_async_task
参数调整可以同时运行的task_limit
的数量。
免责声明:我是项目维护者。