I am trying to wrap my head around promise object in JavaScript. So here I have this little piece of code. I have a promise object and two console.log() on either side of the promise object. I thought it would print
hi
There!
zami
but it printed
hi
zami
There!
Why it is like that? I have zero understanding on how promise works, but I understand how asynchronous callback works in JavaScript. Can any one shed some light on this topic?
console.log('hi');
var myPromise = new Promise(function (resolve, reject) {
if (true) {
resolve('There!');
} else {
reject('Aww, didn\'t work.');
}
});
myPromise.then(function (result) {
// Resolve callback.
console.log(result);
}, function (result) {
// Reject callback.
console.error(result);
});
console.log('zami');
Summary:
A promise in Javascript is an object which represent the eventual completion or failure of an asynchronous operation. Promises represent a proxy for a value which are getting in some point in the future.
A promise can have 3 states which are the following:
Pending: This is the initial state of the promise, the promise is now waiting for either to be resolved or rejected. For example, when are reaching out to the web with an AJAX request and wrapping the request in a promise. Then the promise will be pending in the time window in which the request is not returned.
Fulfilled: When the operation is completed succesfully, the promise is fulfilled. For example, when we are reaching out to be web using AJAX for some JSON data and wrapping it in a promise. When we are succesfully getting data back the promise is said to be fulfilled.
Rejected: When the operation has failed, the promise is rejected. For example, when we are reaching out to be web using AJAX for some JSON data and wrapping it in a promise. When we are getting a 404 error the promise has been rejected.
Promise Constructor:
We can create a promise in the following manner:
let prom = new Promise((res, rej) => {
console.log('synchronously executed');
if (Math.random() > 0.5) {
res('Success');
} else {
rej('Error');
}
})
prom.then((val) => {
console.log('asynchronously executed: ' + val);
}).catch((err) => {
console.log('asynchronously executed: ' + err);
}).finally(() => {
console.log('promise done executing');
});
console.log('last log');
Points of interest:
The code inside the promise constructor is synchronously executed.
then method takes as a first argument a callback which is asynchronously executed on promise fulfillment.
then method takes as a second argument a callback which is asynchronously executed on promise rejection. However we are usually using the catch method for this (because this is more verbose), which also takes a callback which is asynchronously executed on promise rejection. catch is essentially the same as then(null, failCallback).
The then callback receives as a first argument the resolved value (the string 'success' in this case).
The catch callback receives as a first argument the rejected value (the string 'Error' in this case).
The finally method receives a callback which is executed on both promise fulfillment and rejection. Here we can write 'cleanup' code which need to be executed always regardless of promise outcome.
Your example:
In your code 'Zami' was printed before 'there' because the log which logged 'there' was in a then callback function. We earlier pointed out that these callbacks are executed asynchronously and thus will be executed last.
Promise execution is asynchronous, which means that it's executed, but the program won't wait until it's finished to continue with the rest of the code.
Basically, your code is doing the following:
Log 'Hi'
Create a promise
Execute the promise
Log 'zami'
Promise is resolved and logs 'There'.
If you want it to print 'Hi there, zami', you will have to
myPromise.then(function (result) {
// Resolve callback.
console.log(result);
console.log('zami');
}, function (result) {
// Reject callback.
console.error(result);
});
Even though you resolved the promised synchronously, the handlers you pass into then get called asynchronously. This is according to the defined specification:
onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack
I would recommend you to understand how event loop works in JavaScript.
take time and watch this Video.
It will clear your doubts.
A Promise is an object representing the eventual completion or failure of an asynchronous operation.
Below is the example of promise:
const post = new Promise((resolve, reject) => {
resolve("Appended from getPostWithPromise()");
});
const getPostWithPromise = function () {
post
.then(function (fulfilled) {
$("body").append("<div>" + fulfilled + "</div>");
})
.catch(function (error) {
console.log(error);
});
}
function getPostWithoutPromise() {
$("body").append("<div>Appended from getPostWithoutPromise()</div>");
}
$(function () {
getPostWithPromise(); // this will print last
getPostWithoutPromise(); // this will print first
$("body").append("<div>Appended directly</div>"); // second
});
you can test it => JavaScript Promises example
for detail understanding you can read this post => https://scotch.io/tutorials/javascript-promises-for-dummies
Promise:
new Promise((resolve, reject) => {
resolve(whateverObject)
reject(whateverErrorObject)
})
It is just object that can be chained with then()
You also can make promise! you can return whatever object in that success parameter (resolve) and error parameter (reject)
so very simple concept bro!
Promises are objects.
Each promise object has a then method.
The then method of the promise object accepts a function as a first parameter.
If we call the then method of a promise, the callback function will be executed once the promise gets resolved.
Flow of execution
const promiseObj = new Promise((res, rej) => {
console.log("Promise constructor are synchronously executed");
res("Hii Developer");
})
const callbackFunction = (resolvedValue) => console.log("Resolved Value ", resolvedValue);
promiseObj.then(callbackFunction);
console.log("I am the executed after the constructor");
In the above example, we have created a promise object using the Promise constructor.
The constructor function is synchronously executed.
After creating the promise object, we are calling the then method of the promise object. We have passed a callback function in the first argument of the then method. This callback function will be executed once the promise gets resolved and the stack of the js engine gets empty.
Promise is a object that represents the completion or failure of a event . Promise is a asynchronous thing in JS which means that it's executed, but the program won't wait until it's finished to continue with the rest of the code. So it wont be executed simultaneously. It would take time to either complete or fail for a given task and then execution.
In your Case
log'Hi'.
First your mypromise variable will store a promise object i.e either rejected or resolved(for this, it would take time)
But JS engine will execute further code first then the asynchronous task. SO u will get 'zami'.
once the promise resolved or rejected. It will be called or used wherever it is used in the code. In this case ,it is resolved and log 'there!' in console.
let prom = new Promise((res, rej) => {
console.log('synchronously executed');
if (Math.random() > 0.5) {
res('Success');
} else {
rej('Error');
}
})
prom.then((val) => {
console.log('asynchronously executed: ' + val);
}).catch((err) => {
console.log('asynchronously executed: ' + err);
}).finally(() => {
console.log('promise done executing');
});
console.log('last log');
Related
I am trying to wrap my head around promise object in JavaScript. So here I have this little piece of code. I have a promise object and two console.log() on either side of the promise object. I thought it would print
hi
There!
zami
but it printed
hi
zami
There!
Why it is like that? I have zero understanding on how promise works, but I understand how asynchronous callback works in JavaScript. Can any one shed some light on this topic?
console.log('hi');
var myPromise = new Promise(function (resolve, reject) {
if (true) {
resolve('There!');
} else {
reject('Aww, didn\'t work.');
}
});
myPromise.then(function (result) {
// Resolve callback.
console.log(result);
}, function (result) {
// Reject callback.
console.error(result);
});
console.log('zami');
Summary:
A promise in Javascript is an object which represent the eventual completion or failure of an asynchronous operation. Promises represent a proxy for a value which are getting in some point in the future.
A promise can have 3 states which are the following:
Pending: This is the initial state of the promise, the promise is now waiting for either to be resolved or rejected. For example, when are reaching out to the web with an AJAX request and wrapping the request in a promise. Then the promise will be pending in the time window in which the request is not returned.
Fulfilled: When the operation is completed succesfully, the promise is fulfilled. For example, when we are reaching out to be web using AJAX for some JSON data and wrapping it in a promise. When we are succesfully getting data back the promise is said to be fulfilled.
Rejected: When the operation has failed, the promise is rejected. For example, when we are reaching out to be web using AJAX for some JSON data and wrapping it in a promise. When we are getting a 404 error the promise has been rejected.
Promise Constructor:
We can create a promise in the following manner:
let prom = new Promise((res, rej) => {
console.log('synchronously executed');
if (Math.random() > 0.5) {
res('Success');
} else {
rej('Error');
}
})
prom.then((val) => {
console.log('asynchronously executed: ' + val);
}).catch((err) => {
console.log('asynchronously executed: ' + err);
}).finally(() => {
console.log('promise done executing');
});
console.log('last log');
Points of interest:
The code inside the promise constructor is synchronously executed.
then method takes as a first argument a callback which is asynchronously executed on promise fulfillment.
then method takes as a second argument a callback which is asynchronously executed on promise rejection. However we are usually using the catch method for this (because this is more verbose), which also takes a callback which is asynchronously executed on promise rejection. catch is essentially the same as then(null, failCallback).
The then callback receives as a first argument the resolved value (the string 'success' in this case).
The catch callback receives as a first argument the rejected value (the string 'Error' in this case).
The finally method receives a callback which is executed on both promise fulfillment and rejection. Here we can write 'cleanup' code which need to be executed always regardless of promise outcome.
Your example:
In your code 'Zami' was printed before 'there' because the log which logged 'there' was in a then callback function. We earlier pointed out that these callbacks are executed asynchronously and thus will be executed last.
Promise execution is asynchronous, which means that it's executed, but the program won't wait until it's finished to continue with the rest of the code.
Basically, your code is doing the following:
Log 'Hi'
Create a promise
Execute the promise
Log 'zami'
Promise is resolved and logs 'There'.
If you want it to print 'Hi there, zami', you will have to
myPromise.then(function (result) {
// Resolve callback.
console.log(result);
console.log('zami');
}, function (result) {
// Reject callback.
console.error(result);
});
Even though you resolved the promised synchronously, the handlers you pass into then get called asynchronously. This is according to the defined specification:
onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack
I would recommend you to understand how event loop works in JavaScript.
take time and watch this Video.
It will clear your doubts.
A Promise is an object representing the eventual completion or failure of an asynchronous operation.
Below is the example of promise:
const post = new Promise((resolve, reject) => {
resolve("Appended from getPostWithPromise()");
});
const getPostWithPromise = function () {
post
.then(function (fulfilled) {
$("body").append("<div>" + fulfilled + "</div>");
})
.catch(function (error) {
console.log(error);
});
}
function getPostWithoutPromise() {
$("body").append("<div>Appended from getPostWithoutPromise()</div>");
}
$(function () {
getPostWithPromise(); // this will print last
getPostWithoutPromise(); // this will print first
$("body").append("<div>Appended directly</div>"); // second
});
you can test it => JavaScript Promises example
for detail understanding you can read this post => https://scotch.io/tutorials/javascript-promises-for-dummies
Promise:
new Promise((resolve, reject) => {
resolve(whateverObject)
reject(whateverErrorObject)
})
It is just object that can be chained with then()
You also can make promise! you can return whatever object in that success parameter (resolve) and error parameter (reject)
so very simple concept bro!
Promises are objects.
Each promise object has a then method.
The then method of the promise object accepts a function as a first parameter.
If we call the then method of a promise, the callback function will be executed once the promise gets resolved.
Flow of execution
const promiseObj = new Promise((res, rej) => {
console.log("Promise constructor are synchronously executed");
res("Hii Developer");
})
const callbackFunction = (resolvedValue) => console.log("Resolved Value ", resolvedValue);
promiseObj.then(callbackFunction);
console.log("I am the executed after the constructor");
In the above example, we have created a promise object using the Promise constructor.
The constructor function is synchronously executed.
After creating the promise object, we are calling the then method of the promise object. We have passed a callback function in the first argument of the then method. This callback function will be executed once the promise gets resolved and the stack of the js engine gets empty.
Promise is a object that represents the completion or failure of a event . Promise is a asynchronous thing in JS which means that it's executed, but the program won't wait until it's finished to continue with the rest of the code. So it wont be executed simultaneously. It would take time to either complete or fail for a given task and then execution.
In your Case
log'Hi'.
First your mypromise variable will store a promise object i.e either rejected or resolved(for this, it would take time)
But JS engine will execute further code first then the asynchronous task. SO u will get 'zami'.
once the promise resolved or rejected. It will be called or used wherever it is used in the code. In this case ,it is resolved and log 'there!' in console.
let prom = new Promise((res, rej) => {
console.log('synchronously executed');
if (Math.random() > 0.5) {
res('Success');
} else {
rej('Error');
}
})
prom.then((val) => {
console.log('asynchronously executed: ' + val);
}).catch((err) => {
console.log('asynchronously executed: ' + err);
}).finally(() => {
console.log('promise done executing');
});
console.log('last log');
Suppose I have the following Promise:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
const result = doSomeWork();
setTimeout(() => {
resolve(result);
}), 100);
});
}
At which point in time is doSomeWork() called? Is it immediately after or as the Promise is constructed? If not, is there something additional I need to do explicitly to make sure the body of the Promise is run?
Immediately, yes, by specification.
From the MDN:
The executor function is executed immediately by the Promise implementation, passing resolve and reject functions (the executor is called before the Promise constructor even returns the created object)
This is defined in the ECMAScript specification (of course, it's harder to read...) here (Step 9 as of this edit, showing that the executor is called synchronously):
Let completion be Completion(Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).
(my emphasis)
This guarantee may be important, for example when you're preparing several promises you then pass to all or race, or when your executors have synchronous side effects.
You can see from below the body is executed immediately just by putting synchronous code in the body rather than asynchronous:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
console.log("a");
resolve("promise result");
});
}
doSomethingAsynchronous();
console.log("b");
The result shows the promise body is executed immediately (before 'b' is printed).
The result of the Promise is retained, to be released to a 'then' call for example:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
console.log("a");
resolve("promise result");
});
}
doSomethingAsynchronous().then(function(pr) {
console.log("c:" + pr);
});
console.log("b");
Result:
a
b
c:promise result
Same deal with asynchronous code in the body except the indeterminate delay before the promise is fulfilled and 'then' can be called (point c). So a and b would be printed as soon as doSomethingAsynchronous() returns but c appears only when the promise is fulfilled ('resolve' is called).
What looks odd on the surface once the call to then is added, is that b is printed before c even when everything is synchronous.
Surely a would print, then c and finally b?
The reason why a, b and c are printed in that order is because no matter whether code in the body is async or sync, the then method is always called asynchronously by the Promise.
In my mind, I imagine the then method being invoked by something like setTimeout(()=>{then(pr)},0) in the Promise once resolve is called. I.e. the current execution path must complete before the function passed to then will be executed.
Not obvious from the Promise specification why it does this?
My guess is it ensures consistent behavior regarding when then is called (always after current execution thread finishes) which is presumably to allow multiple Promises to be stacked/chained together before kicking off all the then calls in succession.
Yes, when you construct a Promise the first parameter gets executed immediately.
In general, you wouldn't really use a promise in the way you did, as with your current implementation, it would still be synchronous.
You would rather implement it with a timeout, or call the resolve function as part of an ajax callback
function doSomethingAsynchronous() {
return new Promise((resolve) => {
setTimeout(function() {
const result = doSomeWork();
resolve(result);
}, 0);
});
}
The setTimeout method would then call the function at the next possible moment the event queue is free
From the EcmaScript specification
The executor function is executed immediately by the Promise
implementation, passing resolve and reject functions (the executor is
called before the Promise constructor even returns the created object)
Consider the following code:
let asyncTaskCompleted = true
const executorFunction = (resolve, reject) => {
console.log("This line will be printed as soon as we declare the promise");
if (asyncTaskCompleted) {
resolve("Pass resolved Value here");
} else {
reject("Pass reject reason here");
}
}
const myPromise = new Promise(executorFunction)
When we execute the above code, executorFunction will be called automatically as soon as we declare the Promise, without us having to explicitly invoke it.
Suppose I have the following Promise:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
const result = doSomeWork();
setTimeout(() => {
resolve(result);
}), 100);
});
}
At which point in time is doSomeWork() called? Is it immediately after or as the Promise is constructed? If not, is there something additional I need to do explicitly to make sure the body of the Promise is run?
Immediately, yes, by specification.
From the MDN:
The executor function is executed immediately by the Promise implementation, passing resolve and reject functions (the executor is called before the Promise constructor even returns the created object)
This is defined in the ECMAScript specification (of course, it's harder to read...) here (Step 9 as of this edit, showing that the executor is called synchronously):
Let completion be Completion(Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).
(my emphasis)
This guarantee may be important, for example when you're preparing several promises you then pass to all or race, or when your executors have synchronous side effects.
You can see from below the body is executed immediately just by putting synchronous code in the body rather than asynchronous:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
console.log("a");
resolve("promise result");
});
}
doSomethingAsynchronous();
console.log("b");
The result shows the promise body is executed immediately (before 'b' is printed).
The result of the Promise is retained, to be released to a 'then' call for example:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
console.log("a");
resolve("promise result");
});
}
doSomethingAsynchronous().then(function(pr) {
console.log("c:" + pr);
});
console.log("b");
Result:
a
b
c:promise result
Same deal with asynchronous code in the body except the indeterminate delay before the promise is fulfilled and 'then' can be called (point c). So a and b would be printed as soon as doSomethingAsynchronous() returns but c appears only when the promise is fulfilled ('resolve' is called).
What looks odd on the surface once the call to then is added, is that b is printed before c even when everything is synchronous.
Surely a would print, then c and finally b?
The reason why a, b and c are printed in that order is because no matter whether code in the body is async or sync, the then method is always called asynchronously by the Promise.
In my mind, I imagine the then method being invoked by something like setTimeout(()=>{then(pr)},0) in the Promise once resolve is called. I.e. the current execution path must complete before the function passed to then will be executed.
Not obvious from the Promise specification why it does this?
My guess is it ensures consistent behavior regarding when then is called (always after current execution thread finishes) which is presumably to allow multiple Promises to be stacked/chained together before kicking off all the then calls in succession.
Yes, when you construct a Promise the first parameter gets executed immediately.
In general, you wouldn't really use a promise in the way you did, as with your current implementation, it would still be synchronous.
You would rather implement it with a timeout, or call the resolve function as part of an ajax callback
function doSomethingAsynchronous() {
return new Promise((resolve) => {
setTimeout(function() {
const result = doSomeWork();
resolve(result);
}, 0);
});
}
The setTimeout method would then call the function at the next possible moment the event queue is free
From the EcmaScript specification
The executor function is executed immediately by the Promise
implementation, passing resolve and reject functions (the executor is
called before the Promise constructor even returns the created object)
Consider the following code:
let asyncTaskCompleted = true
const executorFunction = (resolve, reject) => {
console.log("This line will be printed as soon as we declare the promise");
if (asyncTaskCompleted) {
resolve("Pass resolved Value here");
} else {
reject("Pass reject reason here");
}
}
const myPromise = new Promise(executorFunction)
When we execute the above code, executorFunction will be called automatically as soon as we declare the Promise, without us having to explicitly invoke it.
Suppose I have the following Promise:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
const result = doSomeWork();
setTimeout(() => {
resolve(result);
}), 100);
});
}
At which point in time is doSomeWork() called? Is it immediately after or as the Promise is constructed? If not, is there something additional I need to do explicitly to make sure the body of the Promise is run?
Immediately, yes, by specification.
From the MDN:
The executor function is executed immediately by the Promise implementation, passing resolve and reject functions (the executor is called before the Promise constructor even returns the created object)
This is defined in the ECMAScript specification (of course, it's harder to read...) here (Step 9 as of this edit, showing that the executor is called synchronously):
Let completion be Completion(Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).
(my emphasis)
This guarantee may be important, for example when you're preparing several promises you then pass to all or race, or when your executors have synchronous side effects.
You can see from below the body is executed immediately just by putting synchronous code in the body rather than asynchronous:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
console.log("a");
resolve("promise result");
});
}
doSomethingAsynchronous();
console.log("b");
The result shows the promise body is executed immediately (before 'b' is printed).
The result of the Promise is retained, to be released to a 'then' call for example:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
console.log("a");
resolve("promise result");
});
}
doSomethingAsynchronous().then(function(pr) {
console.log("c:" + pr);
});
console.log("b");
Result:
a
b
c:promise result
Same deal with asynchronous code in the body except the indeterminate delay before the promise is fulfilled and 'then' can be called (point c). So a and b would be printed as soon as doSomethingAsynchronous() returns but c appears only when the promise is fulfilled ('resolve' is called).
What looks odd on the surface once the call to then is added, is that b is printed before c even when everything is synchronous.
Surely a would print, then c and finally b?
The reason why a, b and c are printed in that order is because no matter whether code in the body is async or sync, the then method is always called asynchronously by the Promise.
In my mind, I imagine the then method being invoked by something like setTimeout(()=>{then(pr)},0) in the Promise once resolve is called. I.e. the current execution path must complete before the function passed to then will be executed.
Not obvious from the Promise specification why it does this?
My guess is it ensures consistent behavior regarding when then is called (always after current execution thread finishes) which is presumably to allow multiple Promises to be stacked/chained together before kicking off all the then calls in succession.
Yes, when you construct a Promise the first parameter gets executed immediately.
In general, you wouldn't really use a promise in the way you did, as with your current implementation, it would still be synchronous.
You would rather implement it with a timeout, or call the resolve function as part of an ajax callback
function doSomethingAsynchronous() {
return new Promise((resolve) => {
setTimeout(function() {
const result = doSomeWork();
resolve(result);
}, 0);
});
}
The setTimeout method would then call the function at the next possible moment the event queue is free
From the EcmaScript specification
The executor function is executed immediately by the Promise
implementation, passing resolve and reject functions (the executor is
called before the Promise constructor even returns the created object)
Consider the following code:
let asyncTaskCompleted = true
const executorFunction = (resolve, reject) => {
console.log("This line will be printed as soon as we declare the promise");
if (asyncTaskCompleted) {
resolve("Pass resolved Value here");
} else {
reject("Pass reject reason here");
}
}
const myPromise = new Promise(executorFunction)
When we execute the above code, executorFunction will be called automatically as soon as we declare the Promise, without us having to explicitly invoke it.
I have the following code and when it's executed, it returns both "rejected" and "success":
// javascript promise
var promise = new Promise(function(resolve, reject){
setTimeout(function(){reject()}, 1000)
});
promise
.catch(function(){console.log('rejected')})
.then(function(){console.log('success')});
Could anyone explain why success is logged?
The then callback gets called because the catch callback is before it, not after. The rejection has already been handled by catch. If you change the the order (i.e. (promise.then(...).catch(...))), the then callback won't be executed.
MDN says that the .catch() method "returns a new promise resolving to the return value of the callback". Your catch callback doesn't return anything, so the promise is resolved with undefined value.
Could anyone explain why success is logged?
In short: a .then following a .catch in a Promise chain will always be executed (unless it itself contains errors).
The theoretical explanation
Your code is actually just a Promise chain which is first executed synchronously setting it up to complete asynchronously afterwards. The Javascript engine will pass on any reject() or Error to the first .then down the chain with a reject callback in it. The reject callback is the second function passed to a .then:
.then(
function (){
//handle success
},
function () {
//handle reject() and Error
})
The use of .catch is just syntactic suger for:
.then(null, function () {
//handle reject() or Error
})
Each of the .then's automatically returns a new Promise which can be acted upon by subsequent .then's (or .catch's which are also .then's).
Visualizing the flow of your promise chain
You can visualize the flow of your code with the following example:
var step1 = new Promise (function (resolve, reject) {
setTimeout(reject('error in step1'), 1000);
})
var step2 = step1.then(null, function () {
// do some error handling
return 'done handling errors'
})
var step3 = step2.then(function () {
// do some other stuff after error handling
return 'done doing other stuff'
}, null)
setTimeout (function () {
console.log ('step1: ', step1);
console.log ('step2: ', step2);
console.log ('step3: ', step3);
console.log();
console.log ('Asynchronous code completed')
console.log();
}, 2000);
console.log ('step1: ', step1);
console.log ('step2: ', step2);
console.log ('step3: ', step3);
console.log();
console.log ('Synchronous code completed')
console.log();
which at runtime will result in the following output in the console:
step1: Promise { <rejected> 'error in step1' }
step2: Promise { <pending> }
step3: Promise { <pending> }
Synchronous code completed
step1: Promise { <rejected> 'error in step1' }
step2: Promise { 'done handling errors' }
step3: Promise { 'done doing other stuff' }
Asynchronous code completed
For those who had a successfully resolved promise and a chain ordered like .then > .catch, but still had both your then and catch called, it may be because your then had an error-throwing bug that you can't see unless you explicitly console the error in your catch. That's one of my pet-peeves with Promises absorbing errors even in strict mode.
const promise = new Promise(resolve => resolve())
.then(() => {
console.log('then');
not.defined = 'This causes the catch to fire even though the original promise resolved successfully.';
})
.catch((e) => {
console.log('catch');
// console.error(e);
});
For me catch() was being called after a succesful promise, and no errors in .then().
The reason was, that I listened to a value that changes with the successful promise, and ran a method.
This method was throwing a silent error, because it was being counted as part of the promise.
Similar to #Timar, For me the reason catch was being called is that "then" contains an exception code. so after executing "then" normally and when it reaches the exception code, it handles the exception in "catch" xD