HTML5中用Web Worker异步处理问卷跳转分支,核心是将纯数据计算逻辑(如条件判断、路径预计算)剥离主线程,通过postMessage传递JSON序列化消息,Worker内用Function构造器安全执行规则并缓存,主线程差分更新DOM。
在 HTML5 中用 Web Worker 异步处理大规模问卷的逻辑跳转分支,核心是把耗时的条件判断、路径计算、依赖校验等逻辑从主线程剥离,避免阻塞 UI 渲染和用户操作。关键不在“能不能做”,而在于“怎么拆得干净、传得安全、同步得及时”。
一、明确哪些逻辑适合扔进 Worker
问卷跳转分支通常涉及:多层嵌套条件(如“若 Q3 选‘其他’且 Q5 > 18,则显示 Q7a-Q7c”)、跨题联动(Q10 答案影响 Q2、Q6、Q15 的显隐)、历史答题状态回溯、甚至简单规则引擎匹配。这些纯数据计算、无 DOM 操作、不依赖 window 或 document 的逻辑,完全可迁移。
- ✅ 适合:条件表达式解析(如将字符串 "Q3==='其他' && Q5>18" 安全求值)、跳转路径预计算、题目可见性批量判定、答题完整性校验
- ❌ 不适合:直接修改表单元素样式、触发动画、调用 alert 或 localStorage(Worker 中无 localStorage,但可用 postMessage 协同主线程操作)
二、设计轻量、可序列化的通信协议
主线程与 Worker 之间只能通过 postMessage() 传递结构化克隆(JSON 可序列化对象),不能传函数、DOM 节点或 class 实例。建议约定统一消息格式:
- 主线程发给 Worker:{"type":"computeJump","data":{"answers":{...},"rules": [...]}}
- Worker 回传:{"type":"jumpResult","visible":["Q1","Q3","Q7a"],"hidden":["Q4","Q6"],"next":"Q3"}
- 规则数组 rules 建议预编译为 JSON 表达式树或简化 DSL(如 {"if":{"Q3":"其他","Q5":{">":18}},"then":["Q7a","Q7b"]}),避免在 Worker 中 eval 字符串
三、Worker 内实现无副作用的跳转引擎
不要在 Worker 里写 jQuery 或依赖外部库。用原生 JS 构建极简规则执行器:
立即学习“前端免费学习笔记(深入)”;
- 用 Function constructor 安全构造判断函数(比 eval 更可控),例如:new Function('Q3','Q5','return Q3==="其他" && Q5>18')
- 对每条规则做缓存:用规则字符串 hash 作 key,避免重复编译
- 支持短路计算:一旦某分支确定显隐,立即终止无关规则遍历(尤其适用于千题级问卷)
- 返回结果带版本号或时间戳,方便主线程做防抖(防止快速输入导致多次跳转覆盖)
四、主线程协同:防抖 + 差分更新 + 状态同步
Worker 返回结果后,主线程不直接全量重绘,而是:
- 用 requestIdleCallback 或 setTimeout(..., 0) 延迟应用跳转,避免与用户输入冲突
- 对比上一次可见题列表,只 show/hide 变更项,减少 DOM 操作
- 将 Worker 中无法处理的操作(如聚焦新题、播放提示音)留在主线程完成
- 监听 onmessageerror 处理序列化失败,降级为同步计算(兜底)
不复杂但容易忽略:Worker 文件必须是独立 .js 脚本(不能是内联 script),且需通过相对/绝对 URL 初始化;现代问卷框架(如 SurveyJS)已内置 Worker 支持,可优先评估封装方案而非从零造轮子。