Skip to content

Commit 9dc9f6d

Browse files
authored
Merge pull request #4 from jjmax75/events
Events examples
2 parents 60f1479 + 80b74f4 commit 9dc9f6d

File tree

9 files changed

+182
-1
lines changed

9 files changed

+182
-1
lines changed

cheatsheet/index.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Node Cheat Sheet
2+
3+
# <a name="Events"></a>Events
4+
5+
Class: events.EventEmitter
6+
7+
```
8+
emitter.addListener(event, listener)
9+
emitter.on(event, listener)
10+
emitter.once(event, listener)
11+
emitter.removeListener(event, listener)
12+
emitter.removeAllListeners([event])
13+
emitter.setMaxListeners(n)
14+
emitter.listeners(event)
15+
emitter.emit(event, [arg1], [arg2], [...])
16+
Event: 'newListener'
17+
```

events/READEME.md

Whitespace-only changes.

events/example-advanced.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// import the base? class, EventEmitter from the events module
2+
const { EventEmitter } = require('events')
3+
4+
// create some listener functions to handle when the events occur.
5+
// `foo` is expecting two parameters to be passed in.
6+
const foo = function foo(baz, qux) {
7+
console.log(`foo executed. baz: ${baz}, qux: ${qux}`)
8+
}
9+
10+
const bar = function bar() {
11+
console.log('bar executed.')
12+
}
13+
14+
const errorProne = function foo(obj) {
15+
this.emit('error', 'I am just not going to work')
16+
}
17+
18+
// create an emitter and bind some events to it
19+
const eventEmitter = new EventEmitter()
20+
21+
// Bind the connection event with the listner1 function
22+
eventEmitter.addListener('foo', foo)
23+
24+
// N.B. `addListener` is the same as `on`.
25+
26+
// Bind the connection event with the listner2 function -
27+
// IMPORTANT!! Listeners are called synchronously in the order in which they were added.
28+
// - i.e. `foo` will be called, and `bar` will be called once `foo` has completed.
29+
// This is to prevent race conditions and logic errors.
30+
// They can switch to an async mode using `setImmediate`.
31+
32+
eventEmitter.once('bar', bar)
33+
eventEmitter.once('liveDangerously', errorProne)
34+
35+
// handle errors in one of the listeners handlers
36+
eventEmitter.on('error', (err) => {
37+
console.error('There was an error!')
38+
})
39+
40+
for(let i = 0; i < 3; i++ ) {
41+
eventEmitter.emit('foo', 'value1', 'value2')
42+
eventEmitter.emit('bar')
43+
eventEmitter.emit('liveDangerously')
44+
}
45+
46+
const eventListeners = EventEmitter.listenerCount(eventEmitter, 'foo')
47+
48+
console.log(EventEmitter.listenerCount(eventEmitter, 'connection') + " Listner(s) listening to connection event")
49+
console.log(eventListeners + " Listner(s) listening to connection event")
50+
console.log('end of file...')

events/example-simple.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// import the class EventEmitter from the events module
2+
const { EventEmitter } = require('events')
3+
4+
// create a listener function. These can be arrow functions, but will
5+
// loose `this` refering to the EventEmitter object
6+
const foo = function foo() {
7+
console.log('foo executed.', this)
8+
}
9+
10+
// create an emitter and bind some events to it
11+
const eventEmitter = new EventEmitter()
12+
13+
// Bind the connection event with the listner1 function
14+
eventEmitter.on('foo', foo)
15+
16+
eventEmitter.emit('foo')

events/example-with-param.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const { EventEmitter } = require('events')
2+
3+
const foo = function foo(bar) {
4+
console.log(`foo has been passed ${bar}`)
5+
}
6+
7+
// create an emitter and bind some events to it
8+
const eventEmitter = new EventEmitter()
9+
10+
eventEmitter.on('foo', foo)
11+
12+
eventEmitter.emit('foo', 'bar')

events/exercise/emailer.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = class Emailer {
2+
3+
send (to, body) {
4+
console.log(`Sending email to ${to} with body '${body}'`)
5+
}
6+
7+
}

events/exercise/solution.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
const Emailer = require('./emailer')
3+
const { EventEmitter } = require('events')
4+
5+
const emailer = new Emailer()
6+
7+
const userEvents = new EventEmitter()
8+
9+
const sendWelcomeEmail = function sendWelcomeEmail(emailAddress) {
10+
emailer.send(emailAddress, `Welcome to our app!`)
11+
}
12+
13+
userEvents.on('newUser', sendWelcomeEmail)
14+
15+
userEvents.emit('newUser', 'example@example.com')

events/index.md

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,65 @@ layout: default.njk
33
title: Events
44
---
55

6-
I've seen things you people wouldn't believe. Attack ships on fire off the shoulder of Orion. I watched C-beams glitter in the dark near the Tannhäuser Gate. All those moments will be lost in time, like control flow.
6+
# Events
7+
8+
The Node.js core API is built around the idea of events being "emitted" and "listened" to. Objects called "emitters" emit _named_ events, that are picked up by "listener" functions.
9+
10+
Objects that emit events extend the `EventEmitter` class. These objects expose an `on` method that allows one or more functions to be attached to named events emitted by the object.
11+
12+
When the EventEmitter object emits an event, all of the functions attached to that specific event are called _synchronously_, in the order they were added. This is to prevent race conditions and logic errors. They can switch to an async mode using `setImmediate`.
13+
14+
## A Simple Example
15+
16+
This example creates an event listener for `foo` events, and an event emitter to fire these events.
17+
18+
```
19+
const { EventEmitter } = require('events');
20+
21+
// create a listener function. These can be arrow functions, but will
22+
// loose `this` refering to the EventEmitter object
23+
const foo = function foo() {
24+
console.log('foo executed.', this)
25+
}
26+
27+
// create an emitter and bind some events to it
28+
const eventEmitter = new EventEmitter()
29+
30+
// Bind the connection event with the listner1 function
31+
eventEmitter.on('foo', foo)
32+
33+
// fire the event
34+
eventEmitter.emit('foo')
35+
```
36+
37+
## Passing parameters
38+
39+
When an event is emitted using the `emit` method, the subsequent arguments are passed through to the listeners.
40+
41+
For example:
42+
43+
```
44+
const foo = function foo(bar) {
45+
console.log(`foo has been passed ${bar}`)
46+
}
47+
48+
// Bind the connection event with the listner1 function
49+
eventEmitter.on('foo', foo)
50+
51+
// fire the event
52+
eventEmitter.emit('foo', 'bar')
53+
```
54+
55+
## Summary
56+
57+
Listeners _listen_ for events, that are _emitted_ from emitters.
58+
59+
Take me to [cheat sheet](../cheatsheet/#events)
60+
61+
## Exercise
62+
63+
Imagine we are building a SaaS that does a number of things when a user creates an account. When a user record
64+
is created, we want to emit a `userCreated` event. One of the listeners for this will email a confirmation
65+
email to that user.
66+
67+
Build an event emitter to simulate the `userCreated` event, and an event listener that sends a confirmation email. There is a mock emailer class in the folder that has a method `send`, which expects an email address and a message body as the parameters.

index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ TODO:
99

1010
- Set out the purpose here and list the sections with links
1111
- Styling and update the default template
12+
13+
14+
[Events](/events)

0 commit comments

Comments
 (0)