{"action":"created","issue":{"url":"https://api.github.com/repos/nodejs/node/issues/6394","repository_url":"https://api.github.com/repos/nodejs/node","labels_url":"https://api.github.com/repos/nodejs/node/issues/6394/labels{/name}","comments_url":"https://api.github.com/repos/nodejs/node/issues/6394/comments","events_url":"https://api.github.com/repos/nodejs/node/issues/6394/events","html_url":"https://github.com/nodejs/node/pull/6394","id":151106238,"number":6394,"title":"events: pass the original listener added by EventEmitter#once to the removeListener handler","user":{"login":"DavidCai1993","id":5886475,"avatar_url":"https://avatars.githubusercontent.com/u/5886475?v=3","gravatar_id":"","url":"https://api.github.com/users/DavidCai1993","html_url":"https://github.com/DavidCai1993","followers_url":"https://api.github.com/users/DavidCai1993/followers","following_url":"https://api.github.com/users/DavidCai1993/following{/other_user}","gists_url":"https://api.github.com/users/DavidCai1993/gists{/gist_id}","starred_url":"https://api.github.com/users/DavidCai1993/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DavidCai1993/subscriptions","organizations_url":"https://api.github.com/users/DavidCai1993/orgs","repos_url":"https://api.github.com/users/DavidCai1993/repos","events_url":"https://api.github.com/users/DavidCai1993/events{/privacy}","received_events_url":"https://api.github.com/users/DavidCai1993/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/nodejs/node/labels/events","name":"events","color":"bfdadc"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":28,"created_at":"2016-04-26T11:13:06Z","updated_at":"2016-04-29T04:26:58Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/nodejs/node/pulls/6394","html_url":"https://github.com/nodejs/node/pull/6394","diff_url":"https://github.com/nodejs/node/pull/6394.diff","patch_url":"https://github.com/nodejs/node/pull/6394.patch"},"body":"##### Checklist\r\n\r\n- [x] tests and code linting passes\r\n- [x] the commit message follows commit guidelines\r\n- [x] a test and/or benchmark is included\r\n\r\n##### Description of change\r\n\r\nWe use the [`_onceWrap`](https://github.com/nodejs/node/blob/master/lib/events.js#L280) 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: \r\n\r\n```js\r\n'use strict'\r\nconst EventEmitter = require('events')\r\n\r\nlet ee = new EventEmitter()\r\n\r\nee.once('test', () => console.log('test'))\r\n\r\nee.on('removeListener', (eventName, listener) => {\r\n  console.log(`eventName: ${eventName}`)\r\n  listener.call(ee)\r\n  listener.call(ee)\r\n  listener.call(ee)\r\n})\r\n\r\nee.emit('test')\r\n// eventName: test\r\n// test\r\n\r\n```\r\n\r\nBut 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:\r\n\r\n```js\r\n'use strict'\r\nconst EventEmitter = require('events')\r\n\r\nlet ee = new EventEmitter()\r\n\r\nee.once('test', () => console.log('test'))\r\n\r\nee.on('removeListener', (eventName, listener) => {\r\n  console.log(`eventName: ${eventName}`)\r\n  listener.listener.call(ee)\r\n  listener.listener.call(ee)\r\n  listener.listener.call(ee)\r\n})\r\n\r\nee.emit('test')\r\n// eventName: test\r\n// test\r\n// test\r\n// test\r\n// test\r\n\r\n```\r\n\r\nBut 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:\r\n\r\n```js\r\n'use strict'\r\nconst EventEmitter = require('events')\r\n\r\nlet ee = new EventEmitter()\r\n\r\nee.once('test', () => console.log('test'))\r\n\r\nee.on('removeListener', (eventName, listener) => {\r\n  console.log(`eventName: ${eventName}`)\r\n  listener()\r\n  listener()\r\n  listener()\r\n})\r\n\r\nee.emit('test')\r\n// eventName: test\r\n// test\r\n// test\r\n// test\r\n// test\r\n\r\n```"},"comment":{"url":"https://api.github.com/repos/nodejs/node/issues/comments/215623762","html_url":"https://github.com/nodejs/node/pull/6394#issuecomment-215623762","issue_url":"https://api.github.com/repos/nodejs/node/issues/6394","id":215623762,"user":{"login":"jasnell","id":439929,"avatar_url":"https://avatars.githubusercontent.com/u/439929?v=3","gravatar_id":"","url":"https://api.github.com/users/jasnell","html_url":"https://github.com/jasnell","followers_url":"https://api.github.com/users/jasnell/followers","following_url":"https://api.github.com/users/jasnell/following{/other_user}","gists_url":"https://api.github.com/users/jasnell/gists{/gist_id}","starred_url":"https://api.github.com/users/jasnell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jasnell/subscriptions","organizations_url":"https://api.github.com/users/jasnell/orgs","repos_url":"https://api.github.com/users/jasnell/repos","events_url":"https://api.github.com/users/jasnell/events{/privacy}","received_events_url":"https://api.github.com/users/jasnell/received_events","type":"User","site_admin":false},"created_at":"2016-04-29T04:26:58Z","updated_at":"2016-04-29T04:26:58Z","body":"yep, I landed the fix for the failing test a few minutes ago. It's unrelated to this change so wouldn't worry about it."}}