You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修正Python异步函数中的同步循环以实现并发请求

解决方案

核心是把两层循环中每个请求对应的协程任务收集起来,通过asyncio.gather()批量并发执行,替代逐次await的同步逻辑。以下是具体实现方式:

步骤1:重构任务生成逻辑

先把需要请求的所有URL对应的协程任务统一收集,避免在循环内逐个await导致串行执行,让所有请求能同时发起。

步骤2:修改主逻辑实现并发

下面是调整后的完整代码示例(假设你原代码的数据源结构如下):

import aiohttp
import asyncio

async def fetch(session, url):
    async with session.get(url) as response:
        # 可根据需求替换为响应解析逻辑,比如response.json()
        return await response.text()

async def main():
    # 示例两层循环的数据源
    categories = ["books", "electronics", "clothing"]
    item_ids = [101, 102, 103]

    async with aiohttp.ClientSession() as session:
        # 收集所有请求任务
        tasks = []
        for category in categories:
            for item_id in item_ids:
                url = f"https://example.com/api/{category}/{item_id}"
                # 创建协程对象,暂不执行
                tasks.append(fetch(session, url))
        
        # 并发执行所有任务,等待全部完成
        results = await asyncio.gather(*tasks)
        
        # 按顺序处理结果(结果顺序与tasks列表顺序完全对应)
        for idx, result in enumerate(results):
            category = categories[idx // len(item_ids)]
            item_id = item_ids[idx % len(item_ids)]
            print(f"完成 {category}-{item_id} 请求,响应摘要: {result[:50]}...")

if __name__ == "__main__":
    asyncio.run(main())

额外优化建议

  • 限制并发数:如果请求量极大(比如数百上千个),可以用asyncio.Semaphore避免触发目标服务器限流:
    async def main():
        categories = ["books", "electronics", "clothing"]
        item_ids = [101, 102, 103]
        # 限制同时最多10个并发请求
        semaphore = asyncio.Semaphore(10)
    
        async def bounded_fetch(session, url):
            async with semaphore:
                return await fetch(session, url)
    
        async with aiohttp.ClientSession() as session:
            tasks = [bounded_fetch(session, f"https://example.com/api/{c}/{i}") 
                     for c in categories for i in item_ids]
            results = await asyncio.gather(*tasks)
            # 后续处理逻辑不变
    
  • 容错处理:给asyncio.gather()添加return_exceptions=True,单个请求失败不会导致整个任务组崩溃,而是返回异常对象便于排查:
    results = await asyncio.gather(*tasks, return_exceptions=True)
    

内容的提问来源于stack exchange,提问作者automation_m

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 03:10:34