Skip to content

Commit

Permalink
Rename to prependListener/prependOnceListener
Browse files Browse the repository at this point in the history
  • Loading branch information
jasnell committed Apr 19, 2016
1 parent 6e49e43 commit 6cba1e6
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 61 deletions.
84 changes: 42 additions & 42 deletions doc/api/events.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -314,42 +314,6 @@ console.log(myErr.eventNames());
// Prints ['foo', 'bar', Symbol('symbol')]
```

### emitter.firstOn(eventName, listener)

* `eventName` {string|Symbol} The name of the event.
* `listener` {Function} The callback function

Adds the `listener` function to the *beginning* of the listeners array for the
event named `eventName`. No checks are made to see if the `listener` has
already been added. Multiple calls passing the same combination of `eventName`
and `listener` will result in the `listener` being added, and called, multiple
times.

```js
server.firstOn('connection', (stream) => {
console.log('someone connected!');
});
```

Returns a reference to the `EventEmitter` so calls can be chained.

### emitter.firstOnce(eventName, listener)

* `eventName` {string|Symbol} The name of the event.
* `listener` {Function} The callback function

Adds a **one time** `listener` function for the event named `eventName` to the
beginning of the listeners array. This listener is invoked only the next time
`eventName` is triggered, after which it is removed.

```js
server.firstOnce('connection', (stream) => {
console.log('Ah, we have our first user!');
});
```

Returns a reference to the `EventEmitter` so calls can be chained.

### emitter.getMaxListeners()

Returns the current max listener value for the `EventEmitter` which is either
Expand Down Expand Up @@ -394,13 +358,13 @@ server.on('connection', (stream) => {
Returns a reference to the `EventEmitter` so calls can be chained.

By default, event listeners are invoked in the order they are added. The
`emitter.firstOn()` method can be used as an alternative to add the event
listener to the beginning of the listeners array.
`emitter.prependListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.

```js
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.firstOn('foo', () => console.log('b'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
Expand All @@ -425,19 +389,55 @@ server.once('connection', (stream) => {
Returns a reference to the `EventEmitter` so calls can be chained.

By default, event listeners are invoked in the order they are added. The
`emitter.firstOnce()` method can be used as an alternative to add the event
listener to the beginning of the listeners array.
`emitter.prependOnceListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.

```js
const myEE = new EventEmitter();
myEE.once('foo', () => console.log('a'));
myEE.firstOnce('foo', () => console.log('b'));
myEE.prependOnceListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
```

### emitter.prependListener(eventName, listener)

* `eventName` {string|Symbol} The name of the event.
* `listener` {Function} The callback function

Adds the `listener` function to the *beginning* of the listeners array for the
event named `eventName`. No checks are made to see if the `listener` has
already been added. Multiple calls passing the same combination of `eventName`
and `listener` will result in the `listener` being added, and called, multiple
times.

```js
server.prependListener('connection', (stream) => {
console.log('someone connected!');
});
```

Returns a reference to the `EventEmitter` so calls can be chained.

### emitter.prependOnceListener(eventName, listener)

* `eventName` {string|Symbol} The name of the event.
* `listener` {Function} The callback function

Adds a **one time** `listener` function for the event named `eventName` to the
beginning of the listeners array. This listener is invoked only the next time
`eventName` is triggered, after which it is removed.

```js
server.prependOnceListener('connection', (stream) => {
console.log('Ah, we have our first user!');
});
```

Returns a reference to the `EventEmitter` so calls can be chained.

### emitter.removeAllListeners([eventName])

Removes all listeners, or those of the specified `eventName`.
Expand Down
12 changes: 6 additions & 6 deletions lib/_stream_readable.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ var StringDecoder;

util.inherits(Readable, Stream);

const has_firston = typeof EE.prototype.firstOn === 'function';
const has_firston = typeof EE.prototype.prependListener === 'function';

function firstOn(emitter, event, fn) {
function prependListener(emitter, event, fn) {
if (has_firston)
return emitter.firstOn(event, fn);
return emitter.prependListener(event, fn);

// This is a brutally ugly hack to make sure that our error handler
// is attached before any userland ones. NEVER DO THIS. This is here
// only because this code needs to continue to work with older versions
// of Node.js that do not include the firstOn() method. The goal is to
// eventually remove this hack.
// of Node.js that do not include the prependListener() method. The goal
// is to eventually remove this hack.
if (!emitter._events || !emitter._events[event])
emitter.on(event, fn);
else if (Array.isArray(emitter._events[event]))
Expand Down Expand Up @@ -579,7 +579,7 @@ Readable.prototype.pipe = function(dest, pipeOpts) {
}

// Make sure our error handler is attached before userland ones.
firstOn(dest, 'error', onerror);
prependListener(dest, 'error', onerror);

// Both close and finish should trigger unpipe, but only once.
function onclose() {
Expand Down
20 changes: 11 additions & 9 deletions lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,10 @@ EventEmitter.prototype.addListener = function addListener(type, listener) {

EventEmitter.prototype.on = EventEmitter.prototype.addListener;

EventEmitter.prototype.firstOn = function firstOn(type, listener) {
return _addListener(this, type, listener, true);
};
EventEmitter.prototype.prependListener =
function prependListener(type, listener) {
return _addListener(this, type, listener, true);
};

function _onceWrap(target, type, listener) {
var fired = false;
Expand All @@ -296,12 +297,13 @@ EventEmitter.prototype.once = function once(type, listener) {
return this;
};

EventEmitter.prototype.firstOnce = function firstOnce(type, listener) {
if (typeof listener !== 'function')
throw new TypeError('"listener" argument must be a function');
this.firstOn(type, _onceWrap(this, type, listener));
return this;
};
EventEmitter.prototype.prependOnceListener =
function prependOnceListener(type, listener) {
if (typeof listener !== 'function')
throw new TypeError('"listener" argument must be a function');
this.prependListener(type, _onceWrap(this, type, listener));
return this;
};

// emits a 'removeListener' event iff the listener was removed
EventEmitter.prototype.removeListener =
Expand Down
8 changes: 4 additions & 4 deletions test/parallel/test-event-emitter-prepend.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ var m = 0;
myEE.on('foo', common.mustCall(() => assert.equal(m, 2)));

// This one comes second.
myEE.firstOn('foo', common.mustCall(() => assert.equal(m++, 1)));
myEE.prependListener('foo', common.mustCall(() => assert.equal(m++, 1)));

// This one comes first.
myEE.firstOnce('foo', common.mustCall(() => assert.equal(m++, 0)));
myEE.prependOnceListener('foo', common.mustCall(() => assert.equal(m++, 0)));

myEE.emit('foo');


// Test fail-back if firstOn is undefined
// Test fail-back if prependListener is undefined
const stream = require('stream');
const util = require('util');

delete EventEmitter.prototype.firstOn;
delete EventEmitter.prototype.prependListener;

function Writable() {
this.writable = true;
Expand Down

0 comments on commit 6cba1e6

Please sign in to comment.