Tasker Goto 跳转与 For End For 循环 实现重复执行的两种方式
为什么需要循环
自动化的很多场景需要"重复做同一件事 N 次":
- 连拍 30 张照片做延时
- 对列表中的每个文件做处理
- 定期发送心跳通知(每 2 分钟一次,直到退出 Profile)
- 直到某个条件满足才停止的轮询
Tasker 提供两种实现循环的方式,选哪种取决于你的需求。
方式一:For/End For
For/End For 是 Tasker 内置的循环结构,最直接、最清晰。它对一个元素集合中的每个元素执行一次循环体。
基本语法
For → %item In → Apple, Banana, Cherry
Popup → "现在处理 %item"
End For
循环会执行 3 次,%item 依次取 Apple、Banana、Cherry。
支持的元素来源
| 来源 | 语法 | 说明 |
|---|---|---|
| 固定列表 | In → A, B, C | 逗号分隔的固定值 |
| 变量拆分 | In → %Items(配合 Variable Split) | 动态列表 |
| 数字范围 | In → 1 To 10 | 从 1 到 10,每次 +1 |
| 正则匹配 | Match → 正则 | 从另一个变量中提取匹配 |
For 数字范围示例
For → %i In → 1 To 30
Take Photo → /sdcard/timelapse/photo_%i.jpg
Wait → 10 秒
End For
→ 拍 30 张照片,间隔 10 秒,用于延时摄影。
For + Variable Split 处理 CSV
# 假设 %CSVContent = "小明,30,程序员\n小红,25,设计师\n老王,45,产品经理"
Variable Split %CSVContent By → 换行符
# 现在 %CSVContent1 = "小明,30,程序员", %CSVContent2 = "小红,25,设计师", ...
For → %row In → %CSVContent1, %CSVContent2, %CSVContent3
Variable Split %row By → 逗号
# %row1 = 名字, %row2 = 年龄, %row3 = 职业
Write File → 添加到联系人
End For
For 的嵌套
For 可以嵌套:
For → %hour In → 0 To 23
For → %minute In → 0, 15, 30, 45
# 每小时的这 4 个时间点都执行
Notify → "提醒"
End For
End For
方式二:Goto + If
在 For/End For 之前,Tasker 只能用 Goto 实现循环。现在 Goto 主要用于 For 无法覆盖的场景——比如"直到条件满足才停"的轮询、或需要后退/前进的自由跳转。
Goto 基本语法
Goto 的工作方式:
- 在 Task 的某个 Action 上设置一个标签(Label)
- 在另一个位置添加 Goto 标签名 → Task 跳转到那个标签继续执行
Goto 实现轮询
轮询场景特别适合 Goto + If:
Label → Loop(在某个 Action 上长按 → 添加标签)
1. Get Location → 等待精度 < 50 米
2. If → 已到达目的地
Stop(到达了就退出)
Else
Goto → Loop(没到达就回去继续等)
Endif
Goto + If 实现"至少执行一次"的循环
Label → Retry
1. HTTP Request → 调用 API
2. If → %HTTPCODE != 200
Wait → 5 秒
Goto → Retry
Else
Notify → "API 调用成功"
Endif
→ API 调用失败时最多重试,直到成功或 Task 被其他方式终止。
Goto 的风险
Goto 是出了名的容易写死循环。典型坏味道:
# 危险:如果 If 条件永远不满足,就是死循环
Goto → Loop
Label → Loop
If → 某个几乎不可能满足的条件
Stop
Endif
避免死循环的保护措施
- 计数器 + If:每次循环 +1,超过上限就 Stop
Variable Set %RetryCount, 0
Label → Retry
1. HTTP Request
2. Variable Add %RetryCount, 1
3. If → %RetryCount > 5
Notify → "重试 5 次失败,放弃"
Stop
Else If → %HTTPCODE != 200
Wait → 5 秒
Goto → Retry
Endif
- Kill All 按钮:Task 编辑界面底部有个"强制终止"按钮,紧急情况用它救场
For vs Goto 选择指南
| 场景 | 推荐 | 原因 |
|---|---|---|
| 已知数量的重复 | For | 简洁、不会死循环 |
| 遍历列表/数组 | For | 内置支持 |
| 直到条件满足才停 | Goto + If | For 无法表达"不确定次数" |
| 复杂跳转(非后退) | Goto | For 只能顺序遍历 |
| 并发并行 | 都不行 | Tasker 的 Task 是单线程顺序执行的 |
For 中提前退出
For 循环没有原生的 Break 动作,但可以用 Stop 或 Goto 变通:
方案一:Stop 终止整个 Task
For → %f In → 文件列表
If → %f = 目标文件
Notify → "找到目标:%f"
Stop → 找到就停,整个 Task 结束
Endif
End For
方案二:Goto 跳出 For 继续后续 Action
For → %f In → 文件列表
If → %f = 目标文件
Variable Set %FoundFile, %f
Goto → AfterLoop
Endif
End For
Label → AfterLoop
Notify → "找到:%FoundFile"
注意:Goto 跳到 For 外面是合法的,但跳回 For 内部会很混乱,不推荐。
性能:循环中的 Wait
在循环里加 Wait 时要注意:
- Wait 会暂停整个 Task 的执行
- 如果 Task 同时在处理其他 Profile,Wait 期间那个 Profile 会被阻塞
- 长时间等待建议放到单独的 Task 里
For + Wait 实现"每分钟检查一次电池":
Profile:定期电池检查
State:Variable Value %CheckBattery = 1(启动开关)
Enter Task:
For → %i In → 1 To 60(检查 60 次,每次间隔 1 分钟 = 共 1 小时)
1. If → %BATT < 20
Notify → "低电量提醒"
Stop
Endif
2. Wait → 1 分钟
End For