variable, and it won’t have the same value inside a callback. So we have to save the
current value of
this
so we can use it inside the promises.
The magic happens when we call
countdown.emit('tick', i)
. Anyone who wants
to listen for the
tick
event (we could have called it anything we wanted; “tick”
seemed as good as anything) can do so. Let’s see how we would use this new,
improved countdown:
const
c
=
new
Countdown
(
5
);
c
.
on
(
'tick'
,
function
(
i
) {
if
(
i
>
0
)
console
.
log
(
i
+
'...'
);
});
c
.
go
()
.
then
(
function
() {
console
.
log
(
'GO!'
);
})
.
catch
(
function
(
err
) {
console
.
error
(
err
.
message
);
})
The
on
method of
EventEmitter
is what allows you to listen for an event. In this
example, we provide a callback for every
tick
event. If that
tick
isn’t
0
, we print it
out. Then we call
go
, which starts the countdown. When the countdown is finished,
we log
GO!
. We could have, of course, put the
GO!
inside the
tick
event listener, but
doing it this way underscores the difference between events and promises.
What we’re left with is definitely more verbose than our original
countdown
function,
but we’ve gained a lot of functionality. We now have complete control over how we
report the ticks in the countdown, and we have a promise that’s fulfilled when the
countdown is finished.
We still have one task left—we haven’t addressed the problem of a superstitious
Count
down
instance continuing to count down past 13, even though it’s rejected the
promise:
const
c
=
new
Countdown
(
15
,
true
)
.
on
(
'tick'
,
function
(
i
) {
// note we can chain the call to 'on'
if
(
i
>
0
)
console
.
log
(
i
+
'...'
);
});
c
.
go
()
.
then
(
function
() {
console
.
log
(
'GO!'
);
})
.
catch
(
function
(
err
) {
console
.
error
(
err
.
message
);
})
Promises | 209