Reputation: 1412
It's not much I discovered Javascript Promise
.
However I found out a behaviour I couldn't understand concerning the nesting of (new or returned) Promise
inside Promises
That's the background (extPromiseX
is a third-party function returning Promise
):
function myAction(param) {
return extPromise1(sql).then((result) => {
[...]
return extPromise2(sql2).then((result) => {
[...]
return extPromise3(sql3);
})
});
}
// Main Process
myAction(...)
.then(() => {
console.log('Process Terminated');
}).catch((error) => {
console.error('Exit with error', error);
});
Now, as expected, I got from the console, in
1) extPromise1 completed
2) extPromise2 completed
3) extPromise3 completed
4) Process Terminated
function myAction(param) {
return new Promise(function() {
if (itsAllOkWithInputs) {
// Some sync code here
return extPromise1(sql).then((result) => {
[...]
return extPromise2(sql2).then((result) => {
[...]
return extPromise3(sql3);
})
})
} else {
throw 'Something went wrong';
}
});
}
// Main process
myAction(...)
.then(() => {
console.log('Process Terminated');
}).catch((error) => {
console.error('3) --> Exit with error', error);
})
In this second case extPromise
s are executed but the very first Promise
remains pending (confirmed by debug). So the console shows:
1) extPromise1 completed
2) extPromise2 completed
3) extPromise3 completed
I empirically realized that I had to change myAction
function as follow for the code to work:
function myAction(param) {
return new Promise(function(resolve, reject) {
if (itsAllOkWithInputs) {
// Some sync code here
let ep = extPromise1(sql).then(...);
resolve(ep);
} else {
throw 'Something went wrong';
}
});
}
My question:
I thought returning a promise inside another parental one would make
the parent resolving with the results of the child. This is the case
inside the then
code block applied to the external promises. Why
this is not valid for the new Promise
case?
Upvotes: 2
Views: 146
Reputation: 21430
new Promise(function() {
You are not using neither resolve
nor reject
arguments (you actually even haven't declared them), so the promise will never get resolved or rejected. All other stuff is irrelevant.
If your function returns promise, you have to simply call it and return a result. If you don't know whether the function return promise or just a value, you can wrap it's call into Promise.resolve
, but not in new Promise
.
Upvotes: 1
Reputation: 138417
Because .then
is meant to chain promises. You can return a Promise from inside the then callback, and then itself will return a new Promise.
The Promise constructor is supposed to construct a Promise from an underlying callback. If you return a Promise from inside a Promise constructor, you are doing something wrong conceptually. And that's why it does not work.
function myAction(param) {
if (itsAllOkWithInputs) {
return extPromise1(sql).then(...);
} else {
return Promise.reject('Something went wrong');
}
}
// OR
async function myAction(param) {
if (itsAllOkWithInputs) {
await extPromise1(sql);
} else {
throw 'Something went wrong';
}
}
Upvotes: 2