CNode

node lib/events.js 疑问

问答
Mmario56发布于9 年前最后回复9 年前9 回复4638 浏览0 收藏

一段代码如下: 来源

function emitOne(handler, isFn, self, arg1) {
  if (isFn)
    handler.call(self, arg1);
  else {
    var len = handler.length;
    var listeners = arrayClone(handler, len);
    for (var i = 0; i < len; ++i)
      listeners[i].call(self, arg1);
  }
}

问题

在循环执行listener时候为啥要使用 arrayClone? 不直接使用handler[i].call(self, args1)呢?

查看回复

回复 (9)

Z
zhanzhenzhen#1·9 年前

不太清楚,可能是为了避免副作用~不过看了下源码,好像也没什么副作用,这就奇怪了。。。

M
mario56#3·9 年前

@i5ting , @yjhjstz 有人吗

W
wocaatm#5·9 年前

666666

D
DavidCai1993#6·9 年前

https://cnodejs.org/topic/571e0c445a26c4a841ecbcf1 楼主可以参考一下这个帖子和下面的讨论

Y
yjhjstz#8·9 年前

本质上是为了避免出现递归的回调。

M
mario56#9·9 年前

如果防止在一个事件监听器中监听同一个事件,接而导致死循环?

function emitOne(handler, isFn, self, arg1) {
  if (isFn)
    handler.call(self, arg1);
  else {
    var len = handler.length;
    var listeners = arrayClone(handler, len);
    for (var i = 0; i < len; ++i)
      listeners[i].call(self, arg1);//或者 handler[i].call(self, arg1);
  }
}

用户代码:

'use strict'
const EventEmitter = require('events')

let myEventEmitter = new EventEmitter()

myEventEmitter.on('wtf', function wtf () {
  myEventEmitter.on('wtf', wtf)
})

myEventEmitter.emit('wtf')

events.js 中使用 listeners[i].call(self, arg1);//或者 handler[i].call(self, arg1); 都不会导致死循环。

或许说 arrayClone 是为了防止已注册监听器的变动(如删 / 改)更合适? 引用自 @DavidCai1993

参与回复
登录后即可参与回复。登录