云函数是微信小程序云开发的核心能力之一,但很多人只知道通过前端调用来执行函数,却忽略了它还有定时触发的能力。比如每天凌晨统计数据、每十分钟同步一次第三方接口、定时清理过期文件,这些场景都不适合靠用户打开小程序来触发,用定时触发器才是正解。定时触发器的配置核心就是一份config.json加上一段cron表达式,配置不复杂,但cron写法有一些细节坑,本文会把配置、部署、日志查看、常见问题一次性讲清楚。

一、定时触发器的基本配置方法
云函数的定时触发器不是在控制台点出来的,而是通过函数目录下的配置文件声明。在你的云函数文件夹(比如cloudfunctions/timerTask)里新建一个config.json文件,写入如下内容:
{
"triggers": [
{
"name": "myTimer",
"type": "timer",
"config": "0 0 2 * * * *"
}
]
}
这段配置的含义是:创建一个名为myTimer的定时触发器,每天凌晨两点执行一次。注意几个要点:name是触发器名称,同一个函数下不能重复;type固定为timer;config字段就是cron表达式,必须用双引号包成一个字符串。
配置写好后,关键一步是上传。在微信开发者工具中,右键点击该云函数目录,选择“上传并部署:云端安装依赖”是不够的,必须选择“上传并部署:所有文件”,或者单独右键选择“上传触发器”,这样config.json里的触发器才会真正同步到云端。很多人配置了却一直不执行,问题就出在这一步:只部署了代码没部署触发器。判断触发器是否上传成功,可以打开云开发控制台,进入“云函数”列表,点进对应函数,在“触发器”页签里能看到myTimer就说明成功了。
二、cron表达式写法详解与常用示例
云开发定时触发器的cron表达式和Linux标准的五段式cron不同,它采用七段式,从左到右依次是:秒、分、时、日、月、星期、年,其中年可以省略。每一段之间用空格分隔,支持*表示任意值,支持-表示范围,支持,列举多个值,还支持/表示步长。
以0 0 2 * * * *为例:第一个0表示第0秒,第二个0表示第0分,2表示凌晨2点,后面的星号表示每天执行。再看几个常用写法:
// 每天早上8点30分执行 "config": "0 30 8 * * * *" // 每隔5分钟执行一次(注意不是每5分钟的第0秒,而是从0分开始步长5) "config": "0 */5 * * * * *" // 每周一到周五早上9点执行(工作日跑批) "config": "0 0 9 * * 1-5 *" // 每月1号凌晨0点执行(月度汇总) "config": "0 0 0 1 * * *" // 每天中午12点和晚上8点各执行一次 "config": "0 0 12,20 * * * *"
有两个非常容易踩的坑需要提醒。第一,星期字段的取值范围是0到6,其中0表示周日,1表示周一,如果你想让任务周一执行,写7是无效的。第二,如果你想写“每秒执行”这类高频任务,虽然语法上可以通过*/1 * * * * * *实现每秒触发,但云函数按调用次数计费,高频定时任务会产生不小的费用,建议最低粒度控制在分钟级。另外,日和星期两个字段如果都写了具体值,是“或”的关系而不是“与”,想表达“每月1号且是周一”这种条件,cron本身做不到,需要在函数代码里自行判断。
三、定时任务日志查看与问题排查
触发器部署成功后,怎么确认函数真的执行了?打开云开发控制台,进入“云函数”页面,找到对应的函数点进去,切换到“日志”页签。这里会列出每次调用的记录,定时触发的调用在“调用来源”一列会标注为“定时触发器”,可以和前端调用区分开。点开某条日志,能看到执行时长、消耗内存、返回结果以及打印的日志内容。
要在日志里看到有用信息,函数代码里必须主动打印日志。推荐用console.log输出关键状态,云函数会自动把这些内容收集到日志系统里。示例代码如下:
// 云函数入口文件 index.js
const cloud = require('wx-server-sdk')
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV })
exports.main = async (event, context) => {
// 定时触发时,event里没有userInfo,可借此判断调用来源
console.log('触发时间:', new Date().toLocaleString())
console.log('触发事件参数:', JSON.stringify(event))
try {
// 这里写你的业务逻辑,例如统计、同步、清理等
const result = await doSomeWork()
console.log('执行成功,结果:', result)
return { code: 0, msg: 'ok' }
} catch (err) {
console.error('执行失败:', err)
return { code: -1, msg: err.message }
}
}
排查问题时按这个思路走:如果日志列表里完全没有定时触发的记录,说明触发器没上传成功,回过头重新上传触发器并检查cron语法;如果有调用记录但状态是失败,点开日志看错误堆栈,最常见的是代码里依赖了event.userInfo导致空引用,定时触发时event里只有触发器信息,没有用户身份。还有一点,日志默认只保留一段时间,重要的执行结果建议落库到云数据库,方便长期追溯。
四、触发器的修改、删除与注意事项
修改触发器的方式和创建一样:改config.json里的cron表达式,然后重新“上传触发器”。云端会以最新配置为准,不需要先删除旧的。但要注意,如果本地把config里的触发器删掉再上传,云端对应的触发器也会被同步删除,这个联动机制要记住,别误操作把线上任务干掉了。
如果不想用开发者工具,也可以通过云开发控制台的可视化界面添加触发器,或者在函数详情页直接编辑cron,两种方式效果一致。此外还有几点实践建议:定时任务里避免写耗时超过函数超时时间的逻辑,超时时间在函数配置里可以调整,默认几秒往往不够用;多个相关任务注意错峰执行,比如统计任务安排在2点、清理任务安排在3点,避免集中占用配额;最后给触发器起一个能自解释的名字,后期在日志列表里筛选时会方便很多。
总结一下,定时触发器的使用就三步:写config.json、上传触发器、去日志页签验证执行。把七段式cron的字段含义记牢,注意触发器必须单独上传这个关键点,再配合日志排查,定时任务基本就能稳定运行了。