will happen only once (if it’s fulfilled, it’ll only be fulfilled once; if it’s rejected, it’ll only
be rejected once). Once a promise has either been fulfilled or rejected, it’s considered
to be settled.
Another convenient advantage of promises over callbacks is that, because they’re just
objects, they can be passed around. If you want to kick off an asynchronous process,
but would prefer someone else handle the results, you can just pass the promise to
them (this would be analogous to giving the reservation pager to a friend of yours—
ostensibly the restaurant won’t mind who takes the reservation as long as the party
size is the same).
Creating Promises
Creating a promise is a straightforward affair: you create a new
Promise
instance with
a function that has
resolve
(fulfill) and
reject
callbacks (I did warn you that prom‐
ises don’t save us from callbacks). Let’s take our
countdown
function, parameterize it
(so we’re not stuck with only a 5-second countdown), and have it return a promise
when the countdown is up:
function
countdown
(
seconds
) {
return
new
Promise
(
function
(
resolve
,
reject
) {
for
(
let
i
=
seconds
;
i
>=
0
;
i
--
) {
setTimeout
(
function
() {
if
(
i
>
0
)
console
.
log
(
i
+
'...'
);
else
resolve
(
console
.
log
(
"GO!"
));
}, (
seconds
-
i
)
*
1000
);
}
});
}
This isn’t a very flexible function right now. We might not want to use the same verbi‐
age—we may not even want to use the console at all. This wouldn’t do us very much
good on a web page where we wanted to update a DOM element with our count‐
down. But it’s a start…and it shows how to create a promise. Note that
resolve
(like
reject
) is a function. You might be thinking “Ah ha! I could call
resolve
multiple
times, and break the er…promise of promises.” You could indeed call
resolve
or
reject
multiple times or mix them up…but only the first call will count. The
promise will make sure that whoever is using your promise will only get a fulfillment
or a rejection (currently, our function doesn’t have a rejection pathway).
Using Promises
Let’s see how we can use our
countdown
function. We could just call it and ignore the
promise altogether:
countdown(5)
. We’ll still get our countdown, and we didn’t have
to fuss with the promise at all. But what if we want to take advantage of the promise?
Here’s how we use the promise that’s returned:
206 | Chapter 14: Asynchronous Programming