PHP Fiber 抛出异常后还能再次 resume 吗
能不能再次 resume(),不看“之前抛过异常”这一个动作,而看异常离开 Fiber 回调时的状态。异常被 Fiber 内部的 catch 接住,Fiber 仍可以在后续再次 Fiber::suspend(),这时可以继续 resume();异常没有被接住,Fiber 回调就以异常结束,Fiber 进入终止状态,之后再调用 resume() 只会得到 FiberError。
官方手册:https://www.php.net/manual/en/class.fiber.php
Fiber::throw()会把异常从当前Fiber::suspend()点注入 Fiber。- 内部捕获后重新挂起,才存在再次
resume()的机会。 - 先检查
isSuspended()和isTerminated(),不要靠猜测调用。
先看异常最终落在哪里
Fiber 有两个容易混淆的“抛异常”入口。回调内部直接 throw,或外部调用 $fiber->throw($exception),最终都要看异常有没有在 Fiber 的调用栈内被处理。只要异常穿出回调,官方定义的终止状态就成立;终止可能来自正常返回,也可能来自未捕获异常。
| 结果 | Fiber 状态 | 后续动作 |
|---|---|---|
| catch 接住并再次 suspend | 仍为 suspended | 可以 resume |
| 异常离开回调 | terminated | 不能 resume |
| 尚未 start 或正在运行 | 不是可恢复点 | 不要调用 resume |

捕获异常后如何保留下一次 resume
下面的例子让 Fiber 先挂起,外部通过 throw() 把异常送到当前挂起点。catch 处理异常后再次挂起,外部才有第二次 resume() 的合法入口。
getMessage());
}
});
// start() 返回第一个挂起点的值。
$first = $fiber->start();
// throw() 会在当前 suspend() 位置抛出异常,而不是让 Fiber 自动重启。
$second = $fiber->throw(new RuntimeException('temporary failure'));
// catch 分支再次 suspend,所以这里仍可合法 resume。
$fiber->resume('continue');
// 只有回调正常结束后,才把 Fiber 视为完成。
var_dump($fiber->isTerminated()); // true
?>
这里的关键不是把异常“重试”一次,而是异常被捕获后,回调仍然有未完成的执行路径。若 catch 中没有第二个 suspend(),回调会继续走到末尾,throw() 调用返回后 Fiber 就已经终止,再调用 resume() 仍然不成立。
未捕获异常时为什么不能恢复
未捕获异常代表 Fiber 的回调已经没有可继续的执行位置。可以把它当作一次失败的协程实例,而不是可重置的任务对象。需要重试时,应新建一个 Fiber,并把输入、重试次数和清理动作交给上层调度器。
start();
try {
// resume() 继续执行后,未捕获异常会从这里冒出。
$failed->resume();
} catch (Throwable $exception) {
// 先记录原异常,再判断状态,禁止把同一实例当作可重试对象。
error_log($exception->getMessage());
}
if ($failed->isTerminated()) {
// 真正的重试应创建 new Fiber,而不是再次调用 $failed->resume()。
$retry = new Fiber(static fn (): string => 'retry-ok');
$retry->start();
}
?>
isTerminated() 在正常返回和抛出异常后都会是 true。而 getReturn() 只适合读取正常返回值;Fiber 因异常终止时,它不能替代异常处理,也不能把失败实例变回 suspended。

调用 resume 前的检查清单
在事件循环、任务池或请求编排器里,把恢复动作收敛到一个小函数更安全。进入恢复前至少判断:Fiber 已启动、当前确实挂起、没有被上一次异常终止。若状态不满足,就返回任务失败或创建新的 Fiber,而不是吞掉 FiberError。
| 检查 | 说明 | 处理建议 |
|---|---|---|
isStarted() | 未启动不能 resume | 先 start |
isSuspended() | 只有挂起点可被恢复 | 调用 resume 或 throw |
isTerminated() | 正常返回或异常都表示结束 | 读取结果或新建 Fiber |
常见问题
Fiber::throw() 后 catch 住异常就一定能 resume 吗?
不一定。catch 之后如果回调直接结束,Fiber 已终止;只有后续路径再次执行 Fiber::suspend(),外部才有新的恢复点。
Fiber::resume() 报 FiberError 是异常没捕获吗?
常见原因是 Fiber 未启动、正在运行或已经终止。先结合 isStarted()、isRunning()、isSuspended() 和 isTerminated() 判断,不要只看错误文字。
失败后怎样实现重试?
保留原异常和输入,完成资源清理后创建新的 Fiber。不要复用已经 terminated 的对象,也不要用反射或状态字段伪造恢复点。
特效变音魔术师评分和评论怎么看?公开评价与功能判断边界说明
- 上一篇
- 特效变音魔术师评分和评论怎么看?公开评价与功能判断边界说明
- 下一篇
- Kubernetes 1.35 中 Pod 重启语义有哪些常见误解
-
- 文章 · php教程 | 15小时前 |
- PHP array_find 怎么同时取得命中的键和值
- 110浏览 收藏
-
- 文章 · php教程 | 19小时前 |
- PHP json_validate 怎么只检查 JSON 而不构造数组
- 425浏览 收藏
-
- 文章 · php教程 | 1天前 | 后端开发 · php教程 · php filter_var FILTER_VALIDATE_BOOLEAN FILTER_NULL_ON_FAILURE 布尔验证
- PHP filter_var 怎么区分验证失败和合法的 false
- 428浏览 收藏
-
- 文章 · php教程 | 1天前 |
- PHP ini_parse_quantity 怎么解析内存大小配置值
- 338浏览 收藏
-
- 文章 · php教程 | 1天前 |
- PHP Randomizer::pickArrayKeys 怎么无重复抽样键名
- 397浏览 收藏
-
- 文章 · php教程 | 1天前 |
- PHP match 为什么使用严格比较
- 414浏览 收藏
-
- 文章 · php教程 | 1天前 | 数据结构 · php教程 · php SplPriorityQueue FIFO 稳定优先队列
- PHP SplPriorityQueue 相同优先级元素顺序怎么控制
- 441浏览 收藏
-
- 文章 · php教程 | 1天前 | 性能优化 · session · php教程 · php session.lazy_write 会话文件 SessionHandler
- PHP session.lazy_write 为什么能减少会话文件写入
- 139浏览 收藏
-
- 文章 · php教程 | 1天前 | 闭包 · php教程 · php Closure::bindTo 闭包作用域
- PHP Closure::bindTo 怎么切换对象与类作用域
- 413浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 345次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 408次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 406次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 369次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 190次使用
-
- 物流异常件转派时如何保留原单号与处理时限
- 2026-09-20 276浏览
-
- Golang异常处理之defer,panic,recover的使用详解
- 2023-01-07 339浏览
-
- Go语言入门Go Web Fiber框架快速了解
- 2022-12-30 126浏览
-
- golang实现PHP数组特性的方法
- 2023-02-16 371浏览
-
- 小学生也能看懂的Golang异常处理recover panic
- 2022-12-30 485浏览
