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

循环中执行异步IO时PdfReader是否会导致API调用串行化失去异步效果?

问题解答
  • 导致API调用串行的不是PdfReader的处理逻辑,而是for循环中直接对process_pdf使用await的写法
  • 你当前实现的process_pdf本身就不满足异步IO要求,就算调整并发逻辑,底层调用依然会阻塞事件循环

串行原因详解

你当前的循环执行逻辑是严格按顺序执行的:

  1. 调用await process_pdf(...),必须等待本次API调用完全返回结果,才会继续后续逻辑
  2. 执行PdfReader读取、加页的同步计算逻辑
  3. 进入下一轮循环,才会发起下一次API调用

整个流程完全是串行的,100次API调用按顺序依次执行,和普通同步for循环效果一致。PdfReader只是await之后的普通同步操作,它本身不是导致串行的原因,就算删掉这部分逻辑,直接在循环里await process_pdf的写法依然是串行的。

现有异步实现的问题

你写的process_pdf虽然加了async关键字,但属于典型的伪异步实现:内部调用的transform_document_api没有加await,说明这是个同步阻塞的API调用。这种实现哪怕放在异步事件循环里运行,依然会卡住整个事件循环,没法实现异步IO的并发效果。如果要做真正的异步,你需要先把transform_document_api替换为异步HTTP客户端(比如aiohttp)实现的接口,调用时加上await。

正确异步并发写法示例

你可以先批量提交所有API请求,等所有结果返回后再统一处理PDF合并逻辑,参考代码:

import asyncio

async def generate_pdf(self):
    # 批量创建所有异步任务,并发发起API请求
    tasks = [process_pdf(self.xsl, xml_data) for _ in range(100)]
    # 等待所有API请求返回结果
    all_data_bytes = await asyncio.gather(*tasks)
    # 统一处理PDF合并
    for i, data_bytes in enumerate(all_data_bytes):
        pallet_pdf = PdfReader(fdata=data_bytes)
        pallet_pdf_output.addpage(pallet_pdf.getPage(i))

async def process_pdf(xsl, xml_data):
    # transform_document_api需替换为异步实现,调用时加await
    res_status, data_bytes = await async_transform_document_api(xml_data, xsl)
    return data_bytes

如果PdfReader相关处理逻辑耗时很高,担心阻塞事件循环,可以把这部分逻辑扔到线程池中运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 12:06:03