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

如何使用asyncio在每分钟整点重复运行多参数异步函数?

用asyncio实现每分钟整点永久重复执行多参数函数

我来帮你搞定这个问题!你已经摸到了asyncio的门儿,差的就是把单次调度改成永久循环调度的逻辑——asyncio.call_at()完全能做到这件事,核心思路就是:每次任务执行完毕后,计算出下一个整点的时间,然后递归调度自己,形成循环。

核心实现思路

  1. 并行执行多参数任务:用asyncio.gather()把所有带不同参数的函数打包成一个协程组,确保它们在整点同时启动。
  2. 计算下一个整点时间:根据当前时间,算出距离下一分钟整的秒数,转换为asyncio事件循环能识别的时间戳。
  3. 递归调度:任务执行完成后,用call_at()调度下一次的执行,实现永久循环。

完整代码示例

import asyncio
from datetime import datetime, timedelta

# 你的带参数业务函数示例
async def your_business_task(param1, param2):
    print(f"[{datetime.now().strftime('%H:%M:%S')}] 执行任务 | 参数: {param1}, {param2}")
    # 替换成你的实际业务逻辑,比如API调用、数据处理等
    await asyncio.sleep(0.5)  # 模拟任务耗时

async def scheduled_job(loop):
    """调度所有任务,并递归安排下一次执行"""
    # 1. 并行执行所有带不同参数的任务
    await asyncio.gather(
        your_business_task("用户A", "订单1001"),
        your_business_task("用户B", "订单1002"),
        your_business_task("用户C", "订单1003")
    )

    # 2. 计算下一个整点的时间(比如当前19:00:23,下一个就是19:01:00)
    now = datetime.now()
    # 计算距离下一分钟整的秒数,避免刚好整点时的误差
    seconds_to_next_minute = 60 - now.second
    if seconds_to_next_minute == 60:
        seconds_to_next_minute = 0
    next_run_time = now + timedelta(seconds=seconds_to_next_minute)

    # 3. 转换为asyncio事件循环的时间戳格式(loop.time()返回的是相对于事件循环启动后的秒数)
    next_run_timestamp = loop.time() + (next_run_time - now).total_seconds()

    # 4. 递归调度下一次任务,用lambda包装确保协程被正确创建
    loop.call_at(next_run_timestamp, lambda: asyncio.create_task(scheduled_job(loop)))

async def main():
    loop = asyncio.get_running_loop()
    # 计算第一次执行的时间:立即调度到下一个整点
    now = datetime.now()
    seconds_to_first_run = 60 - now.second
    if seconds_to_first_run == 60:
        seconds_to_first_run = 0
    first_run_timestamp = loop.time() + seconds_to_first_run

    # 启动第一次调度
    loop.call_at(first_run_timestamp, lambda: asyncio.create_task(scheduled_job(loop)))

    # 让事件循环一直运行(用Event阻塞,直到手动终止)
    await asyncio.Event().wait()

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("程序已终止")

关键细节说明

  • 并行执行:asyncio.gather()会让所有任务同时启动,如果你的任务需要串行执行,把gather换成依次await每个任务即可。
  • 时间计算精度:通过now.second计算等待秒数,能精准对齐到每分钟的00秒位置,避免累积误差。
  • 容错处理:如果某个任务执行时间超过一分钟(比如跑了70秒),下一次调度会在任务完成后立刻计算下一个整点(比如这次19:00:00开始,19:01:10结束,下一次会调度到19:02:00)。如果需要严格整点执行(哪怕上一次任务超时),可以修改时间计算逻辑为直接取datetime(now.year, now.month, now.day, now.hour, now.minute + 1)。

运行效果

启动程序后,你会看到类似这样的输出,每分钟整点准时执行:

[19:00:00] 执行任务 | 参数: 用户A, 订单1001
[19:00:00] 执行任务 | 参数: 用户B, 订单1002
[19:00:00] 执行任务 | 参数: 用户C, 订单1003
[19:01:00] 执行任务 | 参数: 用户A, 订单1001
[19:01:00] 执行任务 | 参数: 用户B, 订单1002
[19:01:00] 执行任务 | 参数: 用户C, 订单1003
...

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:42:21