Even once a promise is considered resolved, the code placed on the lines below these handlers still runs before them, like here:
let promise = Promise.resolve(); promise.then(() => console.log("promise done!")); console.log("code finished"); // this show appears first
Invoking it will first show code finished and then promise done. That is not normal behavior as the promise should be done at the start. To find out what is going go further.
It is necessary to manage asynchronous tasks properly.
In case of the presence of a chain with different .then/catch/finally, each of them runs asynchronously.
If you want to urge code finished execute after promise done, you can place it into the que along with .then, like this:
.then(() => console.log("promise done"))
.then(() => console.log("code finished"));
So, the order can be regarded as intended.
The unhandled rejection can happen in case a promise error can’t be handled at the end of the microtask queue.
As a rule, the .catch handler is added to the promise chain for handling an expected error:
let promise = Promise.reject(new Error("Promise failed")); promise.catch(err => console.log('caught')); // does not run: error handled window.addEventListener('unhandledrejection', event => console.log(event.reason));
But, missing out to add the .catch will make the engine trigger the event, like here:
<html> <title>Title of the document</title> <head></head> <body> <script> let promise = Promise.reject(new Error("Promise failed")); // Promise failed window.addEventListener('unhandledrejection', event => alert(event.reason)); </script> </body> </html>
Also, the error can be handled later, as follows:
<html> <title>Title of the document</title> <head></head> <body> <script> let promise = Promise.reject(new Error("Promise failed")); setTimeout(() => promise.catch(err => alert('caught')), 1000); // Error: Promise failed window.addEventListener('unhandledrejection', event => alert(event.reason)); </script> </body> </html>
Running it will lead to Promise failed first and then to caught.
As we described above, unhandledrejection is created when the microtask queue is complete. The engine investigates the promises. In case of detecting a rejected one, the event occurs.
In the case, demonstrated above, the .catch handler added by setTimeoutoccurs too. But, it triggers after unhandledrejection, hence nothing is changed.
The promise handling process is always asynchronous because all the promise actions pass through the internal microtask queue.
The handlers such as .then/catch/finally should be called after the current code is over. To make sure that these handlers are executed, it is required to add them to the .then call.