events: pass the original listener added by EventEmitter#once to the removeListener handler
Checklist
-
tests and code linting passes -
the commit message follows commit guidelines -
a test and/or benchmark is included
Description of change
We use the _onceWrap
function to wrap the listener added by EventEmitter#once
, and use the flag fired
inside to make sure the listener will only be called once, including the calling in the removeListener
event:
'use strict'
const EventEmitter = require('events')
let ee = new EventEmitter()
ee.once('test', () => console.log('test'))
ee.on('removeListener', (eventName, listener) => {
console.log(`eventName: ${eventName}`)
listener.call(ee)
listener.call(ee)
listener.call(ee)
})
ee.emit('test')
// eventName: test
// test
But by explicitly invoking the listener in the removeListener handler the user expresses a pretty strong intent that the listener should be called. By now we can use a listener.listener
trick to archive this:
'use strict'
const EventEmitter = require('events')
let ee = new EventEmitter()
ee.once('test', () => console.log('test'))
ee.on('removeListener', (eventName, listener) => {
console.log(`eventName: ${eventName}`)
listener.listener.call(ee)
listener.listener.call(ee)
listener.listener.call(ee)
})
ee.emit('test')
// eventName: test
// test
// test
// test
// test
But those who have not read the the code of lib/events.js
should not know this trick at all, and using tricks is alway not a good way. so this PR is to pass the original listener added by EventEmitter#once
to the removeListener
handler:
'use strict'
const EventEmitter = require('events')
let ee = new EventEmitter()
ee.once('test', () => console.log('test'))
ee.on('removeListener', (eventName, listener) => {
console.log(`eventName: ${eventName}`)
listener()
listener()
listener()
})
ee.emit('test')
// eventName: test
// test
// test
// test
// test