Reputation:
I've been trying to figure this one out and I'm wondering how the resolution value gets passed too getAnswer
's then
call. First I return
the result of add
which I think returns a Promise which allows me to use a then
call on the then
method on getAnswer
, but then how does the second return
statement get passed to it?
function add(num1, num2) {
return new Promise((resolve, reject) => {
setTimeout(() => {resolve(num1 + num2);}, 500)
});
}
function getAnswer() {
return add(5, 5).then((res) => {
console.log(res);
return new Promise((resolve, reject) => {
resolve("How does this get passed too getAnswer's then function?");
});
});
}
getAnswer().then((res) => {
console.log(res);
})
Upvotes: 0
Views: 103
Reputation: 2507
The Basics:
add
returns a Promise -- which is an instance of the Promise
object, every instance of Promise
has a then
method which you can use to observe that promise's resolution.
For chaining purposes, then
has been designed in such a way that it returns a Promise itself (so, every then
call in JavaScript will always return a new promise). The promise returned by then
will be resolved with the return value of its handlers (more on this later).
Now, when you say:
return add(5, 5).then((res) => {
console.log(res);
return new Promise((resolve, reject) => {
resolve("How does this get passed too getAnswer's then function?");
});
});
You are not returning add
's result, you are returning the promise that you created by calling then
on add
's result (this is just standard JS behavior).
Your Question:
but then how does the second return statement get passed to it?
Here is what the then
method returns, according to MDN (the parts inside ([])
are my additions):
A Promise in the pending status ([this is what your first
return
statement is actually returning]). The handler function (onFulfilled or onRejected) gets then called asynchronously ([the handler in your example is the function you've passed to thethen
insidegetAnswer
]). After the invocation of the handler function, if the handler function:
- returns a value, the promise returned by then gets resolved with the returned value as its value;
- throws an error, the promise returned by then gets rejected with the thrown error as its value;
- ([this is your case -- your second
return
]) returns an already resolved promise, the promise returned by then gets resolved with that promise's value as its value;- returns an already rejected promise, the promise returned by then gets rejected with that promise's value as its value.
- returns another pending promise object, the resolution/rejection of the promise returned by then will be subsequent to the resolution/rejection of the promise returned by the handler. Also, the value of the promise returned by then will be the same as the value of the promise returned by the handler.
Personally, whenever I see a Promise being returned by then
's handlers, I just assume -- to simplify the situation for my mind -- that the Promise returned by then
originally has been replaced with the Promise that was just returned by one of then
's handlers. Of course, this mental mapping is parallel to the actual functionality, AFAIK.
So, to sum it up:
getAnswer
returns a promise -- created by add(5, 5).then(...)
.then
(getAnswer().then(...)
) -- unrelated here, but this call also creates a promise. add
call (this handler is the function you pass to then
in #1) returns a promise as well, and the rules are that if a handler of then
returns a promise p
, then whenever p
is resolved with a value v
, the original promise -- created by then
-- will be resolved with v
as well.then
in #2 to observe the promise returned by getAnswer()
will be called with the value v
from #3.Upvotes: 1