Flask中实现异步任务有五种路径:一、用Flask原生async/await视图(需ASGI服务器);二、集成Celery+Redis/RabbitMQ(生产推荐);三、线程池执行轻量任务;四、gevent协程化WSGI;五、asyncio.run()临时调度协程。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

如果您在Flask项目中需要执行耗时操作(如发送邮件、调用外部API、批量数据处理),但又不希望阻塞主线程影响响应速度,则必须引入异步任务机制。CodeGeeX本身不直接提供运行时任务调度能力,但可作为辅助工具参与异步任务逻辑的生成与集成。以下是将异步任务能力集成进Flask项目的多种可行路径:
一、使用Flask原生async/await视图(无需额外依赖)
此方法适用于I/O密集型轻量级异步操作,利用Flask 2.0+内置的异步支持,在单个请求生命周期内并发执行协程,不依赖外部消息队列或worker进程。
1、确保已安装支持异步的Flask版本:pip install flask[async]
2、在路由定义中使用async def声明视图函数,并在内部使用await调用异步库(如aiohttp、aiosqlite):
3、避免在async视图中调用同步阻塞函数(如requests.get、time.sleep),否则将导致事件循环挂起。
4、启动应用时需使用ASGI服务器(如hypercorn或uvicorn),而非默认的Werkzeug开发服务器:hypercorn app:app
二、集成Celery + Redis/RabbitMQ(生产级推荐)
此方案将耗时任务从Web进程剥离,交由独立的Celery worker异步执行,具备任务重试、定时调度、结果持久化等能力,适合中高负载场景。
1、安装核心组件:pip install celery redis
2、在Flask应用中初始化Celery实例,并配置CELERY_BROKER_URL与CELERY_RESULT_BACKEND指向Redis服务地址。
3、定义任务函数并使用@celery.task装饰器注册,例如:@celery.task(bind=True)以启用任务上下文绑定。
4、在视图中通过task.delay()或task.apply_async()提交任务,返回AsyncResult对象用于后续状态轮询或结果获取。
三、采用线程池执行简单异步任务(轻量快速落地)
对于无需持久化、不需失败重试、且任务间无强依赖的短时操作,可借助Python标准库concurrent.futures.ThreadPoolExecutor在后台启动线程执行,避免阻塞主线程。
1、在Flask应用初始化阶段创建全局线程池实例:executor = ThreadPoolExecutor(max_workers=4)
2、定义普通同步函数(如send_email(to, subject, body)),不加async修饰。
CodeGeeX 2.21.0是智谱AI推出的AI编程助手版本,对Inline Chat功能进行了重大优化,包括UI设计升级、支持流式输出以提升响应速度,并新增“查看思路”按钮以便理解代码原理。同时,该版本在编辑器中新增CodeLens控件,支持一键“解释”代码或“添加注释”。目前该工具对个人开发者免费开放。
3、在视图中调用executor.submit(func, *args, **kwargs)提交任务,立即返回Future对象。
4、注意:该方式无法跨进程共享,不适用于gunicorn多worker部署场景,且无任务监控与持久化能力。
四、结合gevent实现协程化WSGI服务(兼容旧代码)
此方法不修改现有同步代码结构,而是将整个WSGI服务器替换为基于gevent的协程化运行时,使阻塞调用(如requests、数据库驱动)自动让出控制权,提升并发吞吐。
1、安装gevent相关包:pip install gevent gevent-websocket
2、启动应用时使用gevent作为WSGI服务器:gevent.wsgi.WSGIServer(('127.0.0.1', 5000), app)
3、确保所用第三方库为gevent友好的版本(如requests-gevent或打补丁后的psycopg2),否则仍会阻塞。
4、禁用Flask内置的debug模式与reloader,因gevent不兼容多进程热重载机制。
五、利用asyncio.run()在同步视图中临时调度协程(调试与过渡用途)
当无法重构整个视图为async、又需临时调用一个异步函数时,可在同步函数内使用asyncio.run()启动新事件循环。该方式仅限单次调用,严禁在Web请求中重复创建事件循环。
1、确认当前线程无正在运行的asyncio事件循环:if asyncio.get_event_loop().is_running(): ...
2、封装目标异步函数为独立模块函数,避免闭包捕获Flask上下文。
3、在同步视图中调用:result = asyncio.run(fetch_data_async(url))
4、注意:每次调用asyncio.run()都会创建并关闭全新事件循环,开销较大,不可用于高频路径。










