为什么生成器的下一个函数不能是事件监听器的回调函数?
Why can't the generators next function be a callback function for an event listener
我尝试了一些生成器。当我尝试这段代码时,我得到了意想不到的错误:
Uncaught TypeError: Method [Generator].prototype。下一个调用不兼容的接收器#或在不兼容的HTMLButtonElement上调用CallStarGeneratorMethodIfWrapped方法
我的问题是,它不工作吗?这些错误消息背后的含义是什么?最重要的是;为什么是第一个()。接下来不作为正常函数处理吗?为什么addEventListener关心first()的起源?下一个函数。第一个类型()。接下来在控制台中。它写的是函数。下面是一个与下一个类似的注释函数,除了它总是产生相同的结果。
您可以尝试复制的代码:
<html>
<button id="test">Click</button>
<script>
var first = function* (){
console.log("first click");
yield true;
console.log("second click");
yield true;
};
document.getElementById("test").addEventListener('click', first().next);
/*var wouldwork = function (){
console.log("would work");
return { value: true, done: false };
// same as the next returns
};*/
/*document.getElementById("test").addEventListener('click', wouldwork);*/
</script>
</html>
另一种选择是将next与正确的上下文放在另一个函数中。为此,将迭代器存储在一个变量中。
var iterator = first();
document.getElementById("test").addEventListener('click',
function (event){return iterator.next();}
//context of next is always the correct one
);
如果这种情况经常发生,创建一个名为createNext的新函数是一个好主意,该函数以更纯的函数风格返回next函数
var createNext = function (generatorFunction){
var iterator = generatorFunction();
return function() {
return iterator.next();
};
};
document.getElementById("test").addEventListener('click',
createNext(first)
);
jsFiddle Demo
事件监听的工作方式是,它将使用call
调用函数句柄,并将this
绑定从其执行上下文中分配给被调用的函数句柄。所以this
将被绑定为next
被调用的上下文。这就是为什么它不能正常工作。
接下来的问题是从生成器函数中实际获取函数以进行迭代。"调用生成器函数不会立即执行它的函数体;返回该函数的迭代器对象。"。这意味着,是的,first().next
是一个函数对象,但它不是您想要传递的句柄。您只是想使用迭代器函数本身,但那将是first()
,那么如果您希望它每次都调用next,该如何工作呢?
这里的一个选项是简单地使用生成器函数,然后将迭代器函数作为绑定传入。为了在.next
内部维护迭代器函数的绑定,可以这样做:
document.getElementById("test").addEventListener('click', first().next.bind(first()));
将first()
的迭代器函数绑定到该迭代器函数的.next
函数。有点乱。第一次调用first()公开迭代器函数,然后访问它的下一个函数,第二次调用只是将下一个函数的this
绑定到迭代器函数,否则当eventListener使用call
覆盖this
绑定时,该函数将被覆盖。
你可以在这里阅读更多关于这些生成器函数和它们的迭代器的一般信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
- 双条件jQuery函数事件
- 将函数事件绑定到更改函数的复选框/标签
- 从c#代码后面触发jQuery函数/事件
- 正在解码函数(事件){}的JavaScript语法
- 如何防止我的$('form').submit(函数(事件))应用于某些表单
- 访问PDF.js查看器函数/事件
- 从内部调用 JavaScript 函数事件
- JavaScript/jQuery调用函数事件
- jquery.live('点击',函数(事件)在页面加载时只工作一次
- 如何在JavaScript中跟踪回调函数事件
- 正确删除匿名函数事件处理程序
- jQuery:将 $(this) 传递给命名函数事件处理程序
- 函数(事件)变量是否可以不永久更改实例变量的内容
- Javascript函数事件没有按顺序触发
- 如何按类循环函数事件
- jQuery与对象的绑定函数'事件处理程序
- 函数(事件)在一个Opera上下文菜单扩展
- 用meteor.js响应式调用js函数/事件
- 缩短JavaScript函数事件
- 将onchange函数事件附加到变量