I'm learning Node.js and trying to properly use the mysql2 module. Because of this, I have recently started researching about promises.
I'm writing a kind of "library", so I can practice all these topics, and while doing that, I got into a problem with promise chaining I can't really understand. Any help is well appreciated!
The problem is the following:
Let's say that I have a query
function which fetches the database, process the data and returns a promise, so I can get that data and work with it in some other file.
Now, if I write my query
function like this:
query(){
let p = new Promise((resolve, reject) => {
resolve("Hello world")
});
p.then(data => {
console.log("Hello world a second time!");
}).then(data => {
console.log("Hello world a third time")
})
return p;
}
and I try to "consume" that promise from other file like this:
DBObject.query().then((data) => {
console.log("Hello world from the other file!");
})
Then the output is in the wrong order, the program prints this:
Hello world a second time!
Hello world from the other file!
Hello world a third time
On the other hand, if I change the code in the first file, and I don't try to separate promise chaining, like this:
query(){
let p = new Promise((resolve, reject) => {
resolve("Hello world")
}).then(data => {
console.log("Hello world a second time!");
}).then(data => {
console.log("Hello world a third time")
})
return p;
}
It works just fine, and it prints:
Hello world a second time!
Hello world a third time
Hello world from the other file!
I don't understand this behaviour, I was thinking that declaring then
blocks separately from the promise definition would be the same thing as do promise chaining right when I declare the promise, and it is clearly not like that!
Thanks beforehand for the answers you can give me. Also, It would be great if you could give me some suggestion on how to write code like this correctly. I mean, if I write code that uses promises, what should I return to the user? Another promise? Or just data for they to work with? I would really like writing code that follow the "standard" way of doing things.
Greets to you all! Thank you again.
Promises co-mingle rejected promises and unintended runtime exceptions. Apart from how the API is structured - promises have another major flaw: they treat unintentional native runtime exceptions and intentional rejected promises - which are two drastically different intentions - in the same "path".
There are two ways in which you can handle errors in your promise chain, either by passing an error handler to then block or using the catch operator.
Chaining after a catch It's possible to chain after a failure, i.e. a catch , which is useful to accomplish new actions even after an action failed in the chain. Read the following example: new Promise((resolve, reject) => { console. log("Initial"); resolve(); }) .
When you have one Promise, you can chain any number of Promises onto its .then
. For example
const p = Promise.resolve();
p.then(() => console.log('then 1');
p.then(() => console.log('then 2');
means that p
has two Promises that branch from it when it resolves: 1
and 2
(in addition to the promise p
itself).
p
/ \
/ \
1 2
What you're doing in your first code
let p = new Promise((resolve, reject) => {
resolve("Hello world")
});
p.then(data => {
console.log("second");
}).then(data => {
console.log("third")
})
return p;
is like
"Hello world" = <Promise you return>
|
|
|
second
|
|
|
third = <unused Promise expression that the then chain resolves to>
You have two branches: the Promise you're returning resolves when Hello world
runs, not when third
runs.
On the other hand, when you call .then
multiple times on a Promise, the whole expression evaluates to the Promise that resolves when the final .then
runs:
let p = new Promise((resolve, reject) => {
resolve("Hello world")
}).then(data => {
console.log("Hello world a second time!");
}).then(data => {
console.log("Hello world a third time")
})
return p;
is like
"Hello world"
|
|
'Hello second'
|
|
'Hello third' = <Promise you return>
where the returned Promise is the one that resolves right after Hello third
runs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With