Reputation: 605
When does the finally gets called in the js Promise context?
I thought at first that the finally
will be called after the last then
. But then I understood that it is impossible to determine the last then
. Also my attempt below proves that:
function f(resolve, reject) {
resolve("foo");
};
var p = new Promise(f);
p.then(function(data) {
console.log("data: " + data);
});
p.finally(function(data) {
console.log("in finally");
});
p.then(function(data) {
console.log("data: " + data);
});
Output:
data: foo
in finally
data: foo
So, the finally
is not called after the last then
. And I thought the the finally
should be called after the resolve
then. But in the example code I tried above we can see that it is also not the case (because the registered then
was called between the resolve
and the finally
).
Hence, I am confused and can not understand when will the finally
be called.
Upvotes: 4
Views: 3309
Reputation: 14679
.finally
complements then
and catch
: then
block gets called on fulfillment, catch
gets called on rejection, and finally
gets called in both cases (for example: you make an API call, in then
block you process the data, in catch
block you display error message, in finally
block you hide the loading spinner).
Then the chain continues.
Promise.reject('execute some action')
.then(() => console.log('I\'ll handle success here'))
.catch(() => console.log('error handling'))
.finally(() => console.log('this block will be executed either way'))
.then(() => console.log('and the adventure continues'))
Upvotes: 7
Reputation: 370929
None of your Promises are chained - everything is connected directly to the root p
Promise. So when the p
Promise resolves (or rejects), all .then
and .finally
callbacks attached to that Promise run, probably in the order in which they were attached.
In most situations, the Promises will be chained - (eg .then(() ... ).then
or .then(() ... ).finally
). Then, the finally
would run after the previous .then
completes, or after the previous .then
throws:
function f(resolve, reject) {
resolve("foo");
};
var p = new Promise(f);
p.then(function(data) {
console.log("data: " + data);
})
.finally(function(data) {
console.log("in finally");
});
function f(resolve, reject) {
resolve("foo");
};
var p = new Promise(f);
p.then(function(data) {
console.log("data: " + data);
console.log("About to throw");
throw new Error();
})
.finally(function(data) { // Above Promise throws, so if this was a .then, it wouldn't run
console.log("in finally");
});
// No .catch, so this results in an unhandled Promise rejection
When deciding when to execute, the .finally
doesn't look ahead to see if anything is chained off of it - rather, the .finally
callback executes as soon as the Promise it's called on resolves or rejects.
Upvotes: 1