A Promise is an object that represents the result of an asynchronous operation.
It is important to remember that Promises are not just abstract ways registering callbacks to run when some async code finishes — they represent the results of that async code.
When we write a chain of .then()
invocations, we are not registering multiple callbacks on a single Promise object. Instead, each invocation of the then()
method returns a new Promise object.
That new Promise object is not fulfilled until the function passed to then()
is complete. The value that fulfills promise 1 becomes the input to the callback2()
function. The callback performs some computation and returns a value v
. When the callback returns the value, the promise is resolved with the value v
.
When a Promise is resolved with a value that is not itself a Promise, it is immediately fulfilled with that value.
It is important to understand in this case, so I rephrase: if a callback returns a non-Promise, that return value becomes the value of the promise, and the promise is fulfilled.
If the return value v
is itself a Promise, then the promise is resolved but not yet fulfilled.
Your case:
allow me to post the functions a,b and c here:
let a = function() {
return new Promise( (resolve, reject) => {
setTimeout(() => resolve(1), 300);
});
}
let b = function() {
return new Promise( (resolve, reject) => {
setTimeout(() => resolve(2), 200);
});
}
let c = function() {
return new Promise( (resolve, reject) => {
setTimeout(() => resolve(3), 100);
});
}
and the implementation
a().then( result => console.log(result))
.then( () => {b().then( result => console.log(result))})
.then( () => {c().then( result => console.log(result))});
Here is what is happening
By adding the curly braces to the arrow function body, we no longer get the automatic return.
This function now returns undefined instead of returning a Promise, which means that the current Promise is fulfilled and next stage in this Promise chain will be invoked with undefined as its input.
So, function a
gets invoked, returns a promise, which is, once fulfilled invokes the callback1.
callback 1 returnes undefined
so the promise1 is fulfilled and the next .then()
invokes the callback2.
The callback2 invokes the b
which itself returnes a Promise, but this Promise is not returned by the callback2. The callback2 returns undefined
. The Promise2 is fulfilled with undefined
and life goes on - Callback3 gets invoked.
At this point b
and c
are running simultaneously, and because c
is 100ms faster than b
you get the 1,3,2 order.
Terminology
We say that the promise has been fulfilled if and when the first callback (argument of then method) is called.
And we say that the Promise has been rejected if and when the second callback (argument of then method) is called.
If a Promise is neither fulfilled nor rejected, then it is pending. And once a promise is fulfilled or rejected, we say that it is settled.
If the async code runs normally (and the Promise is fulfilled), then that result is essentially the return value of the code.
If the Promise is fulfilled, then the value is a return value that gets passed to any callback functions registered as the first argument of then().
Promises can also be resolved. It is easy to confuse this resolved state with the fulfilled state or with settled state, but it is not precisely the same as either.
Resolved means that another Promise has been assigned to the value of the current Promise. The current Promise has become associated with, or “locked onto,” another Promise.
We don’t know yet whether the Promise will be fulfilled or rejected, because it is not yet settled. Its fate now depends entirely on what happens to Promise