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

asyncio入门疑问:获取函数返回值与控制代码执行顺序

解决asyncio中接收返回值与等待任务完成的问题

刚接触asyncio确实容易在同步异步的衔接上踩坑,我来帮你一步步搞定这两个问题~

1. 接收findIntersectingFeatures的返回结果

loop.run_in_executor()会返回一个协程对象,你需要用await关键字等待它执行完成,才能拿到真实的返回值并赋值给变量。结合你的代码场景,具体写法如下:

import json
import requests
import time
import asyncio

startTime = time.perf_counter()  # 替换已废弃的time.clock()
out_json = "UML10kmbuffer.json"
intersections = []

# 假设你的findIntersectingFeatures是类似这样的同步查询函数
def findIntersectingFeatures(coords):
    # 模拟调用外部服务的逻辑
    resp = requests.get(f"https://your-service-url.com/api/intersect?coords={coords}")
    return resp.json().get("matched_ids", [])  # 假设返回ID列表

async def main():
    loop = asyncio.get_running_loop()
    # 假设你有一组需要处理的坐标数据
    coords_list = [[116, 39], [120, 31], [113, 23]]  # 示例坐标
    
    for coords in coords_list:
        # 用await等待任务完成,直接接收返回值
        current_result = await loop.run_in_executor(None, findIntersectingFeatures, coords)
        intersections.extend(current_result)  # 把结果存入全局列表
        print(f"当前坐标处理完成,返回ID:{current_result}")

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

这里的核心是await loop.run_in_executor(...):它会暂停当前协程,直到同步函数在线程池里执行完毕,然后把函数的返回值赋值给current_result。

2. 让print语句在所有任务执行完成后再打印

你之前的print提前执行,是因为没有等待所有异步任务完成就触发了打印逻辑。如果想批量并行处理任务,然后统一打印最终结果,可以用asyncio.gather()来收集所有任务,等待全部完成后再执行print:

async def main():
    loop = asyncio.get_running_loop()
    coords_list = [[116, 39], [120, 31], [113, 23]]
    
    # 先把所有异步任务收集到列表中
    tasks = [loop.run_in_executor(None, findIntersectingFeatures, coords) for coords in coords_list]
    # 等待所有任务完成,一次性拿到所有结果
    all_results = await asyncio.gather(*tasks)
    
    # 合并所有结果
    for result in all_results:
        intersections.extend(result)
    
    # 所有任务都完成后,再执行打印
    print(f"所有查询完成,总耗时:{time.perf_counter() - startTime:.2f}秒")
    print(f"匹配到的所有ID:{intersections}")

asyncio.gather()会阻塞当前协程,直到传入的所有任务(也就是每个run_in_executor的调用)全部执行完毕,所以后面的print语句一定会在所有任务结束后才触发。

另外补充个小细节:如果你的查询逻辑允许,也可以把同步的requests换成异步的aiohttp,这样代码会更贴合asyncio的原生异步风格,不过用run_in_executor兼容同步代码的方案完全没问题,适合新手过渡。

内容的提问来源于stack exchange,提问作者J. Skinner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:58:37