JavaScript中yield作为函数参数时的工作原理是什么?
yield 作为函数参数的运行逻辑拆解
你之前认为yield是增强版return的猜测不符合这个场景的逻辑,当yield出现在表达式位置(作为函数参数、赋值给变量等)时,它的核心作用是接收生成器外部next()方法传入的参数。
基础规则先行
- 生成器函数调用后会返回一个生成器实例,初始状态为暂停,内部代码不会立即执行
- 执行到
yield关键词时,生成器会立即暂停,返回yield后跟随的值(如果没有写就返回undefined) - 调用生成器实例的
next(参数)方法时,生成器恢复执行,整个yield表达式的返回值就是你传入的参数
你的代码逻辑拆解
先看核心的生成器实现:
export function * throttle(func, time) { let timerID = null; function throttled(arg) { clearTimeout(timerID); timerID = setTimeout(func.bind(window, arg), time); } while(true) throttled(yield); }
运行流程分步走
- 调用
throttle(console.log, 3000)得到生成器实例thr,此时内部代码还未执行 - 第一次调用
thr.next(''):- 生成器开始执行,进入
while(true)循环,遇到yield立即暂停,本次next()返回结果为{value: undefined, done: false}
- 生成器开始执行,进入
- 后续每次调用
thr.next(待输出的值):- 整个
yield表达式的结果等于你传入的参数,直接作为实参传给throttled函数 - 执行防抖逻辑:清空上一次未执行的定时器,重新设置新的定时器,等待3000ms后执行
console.log(你传入的参数) - 代码循环回到下一个
yield,再次进入暂停状态,等待下一次next()调用
- 整个
你标记的疑问行解释
setTimeout(func.bind(window, arg), time)是标准的预设参数定时器写法:
func.bind(window, arg)会把func的this绑定为window,同时固定第一个参数为arg,返回一个新的函数- 定时器等待
time毫秒后执行这个新函数,相当于延迟执行func.call(window, arg)
这段整体是防抖逻辑,连续多次触发的话只会执行最后一次触发后等待time毫秒的那一次调用。
代码小问题提示
你给出的GeneratorThrottle类有两处笔误:
- 构造方法拼写错误:
constuctor应该为constructor start方法里的thr没有声明,直接赋值会成为全局变量,建议补充let/const声明
内容的提问来源于stack exchange,提问作者coool
相关产品推荐
相关产品推荐

