如何使用Generator实现多句依次输出的JavaScript打字机效果?
用Generator重构JavaScript打字机效果
针对你遇到的嵌套setTimeout难以维护的问题,用Generator可以把异步流程转化为线性写法,大幅提升代码可读性和可维护性。下面是具体的重构方案:
实现步骤
- 封装单句打字逻辑为Promise
先把单个句子的打字动画封装成返回Promise的函数,方便在Generator中等待任务完成:
function typeSentence(selector, text, speed) { return new Promise(resolve => { const element = document.querySelector(selector); element.textContent = ''; let charIndex = 0; const typingTimer = setInterval(() => { element.textContent += text[charIndex]; charIndex++; if (charIndex === text.length) { clearInterval(typingTimer); resolve(); } }, speed); }); }
- 用Generator定义任务顺序
创建Generator函数,按需求的顺序逐个yield打字任务,新增句子只需追加yield语句即可:
function* typeWriterTasks() { // 第一句:h1元素,文本,打字速度70ms/字符 yield typeSentence('h1', 'I am sentence 1', 70); // 第二句:h2元素,文本,打字速度100ms/字符 yield typeSentence('h2', 'I am sentence 2', 100); // 新增句子直接添加yield,无需嵌套 // yield typeSentence('h3', 'I am sentence 3', 80); }
- 编写Generator驱动函数
实现一个自动执行Generator的函数,它会等待每个yield的Promise完成后,再执行下一个任务:
function runGenerator(generatorFn) { const iterator = generatorFn(); function processNext(result) { if (result.done) return; // 等待当前打字任务完成后,执行下一个任务 result.value.then(() => { processNext(iterator.next()); }); } processNext(iterator.next()); }
- 启动打字机效果
最后调用驱动函数,执行所有打字任务:
runGenerator(typeWriterTasks);
HTML部分保持不变
<h1></h1> <h2></h2>
优势说明
- 新增句子只需在
typeWriterTasks中添加一行yield代码,完全避免了原方案的嵌套地狱。 - 任务顺序一目了然,逻辑线性化,更易理解和维护。
- 单个打字逻辑封装后可复用,修改打字规则只需调整
typeSentence函数。
内容的提问来源于stack exchange,提问作者json buoy
相关产品推荐
相关产品推荐

