i had a look at this SO reply for the best way to include an if/else in a promise chain. the accepted solution looks like this:
new Promise(resolve => resolve({success:true}))
.then(value => {
console.log('second block:', value);
if (value.success) {
//skip the rest of this chain and return the value to caller
return value;
}
//do something else and continue
return somethingElse().then(value => {
console.log('3rd block:', value);
return value;
});
}).then(value => {
//The caller's chain would continue here whether 3rd block is skipped or not
console.log('final block:', value);
return value;
});
i played around with it, this does seem to work just fine.
notice the syntax using the two return statements (interesting)
I donāt understand why you would use a success in the resolve return? Thatās why there is a resolve and reject. For me resolve is only called if success is true otherwise reject is called.
I know I can throw an error or reject it on the second block but I have to handle error case which it is not an error case. So how can I achieve this in promise chain? I need a solution without bring any other 3rd party library.
All a bit confusing.
Iām not a fan of nested thenables, seems that is just another version of callback hell to me. Not sure if I have the wrong end of the stick here, but another option might be to use async await.
const somethingElse = async (value) => {
console.log('second block:', value);
return value
}
const foo = async () => {
// switching to true will avoid calling somethingElse
const value = await Promise.resolve({ success: false })
return (!value.success)
? await somethingElse(value)
: value
}
foo()
.then((value) => console.log('final block:', value))
Unless I am mistaken, if the condition is true it will not do other stuff. It will exit out of the function, in this case returning undefined.
The only way I can see it unexpectedly carrying on to do other stuff is if there is an issue with the condition not being explicit enough. Say for instance when dealing with numbers not taking into account that 0 evaluates to false. I have seen that issue before.
i should have mentioned that i am calling promises that are already formatted.
a Knex promise is called to see if a parent table contains a row, and if so the id is returned. if not, the parent row is created and the new id is returned. then the child table is checked, same as parent row.
from the forum comments, i have pieced this little example together to simulate what i need to do.
/* function to return a true or false */
const trueFalse = (delay) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve( Math.random() < 0.5 ); /* random true or false */
}, delay);
});
};
and this block of code will call it once, but for every false, it will try again.
trueFalse(1000)
.then( flag => {
console.log('first then:' + flag);
if (flag) {
return flag;
} else {
console.log('first then trying again');
return trueFalse(2000).then( flag => return flag)
}
})
.then( flag => {
console.log('second then: ' + flag);
if (flag) {
return flag;
} else {
console.log('second then trying again');
return trueFalse(3000).then( flag => return flag )
}
})
.then( flag => {
console.log('third then: ' + flag);
if (flag) {
return flag;
} else {
console.log('third then trying again');
return trueFalse(3000).then( flag => return flag )
}
})
/* notice use of finally rather than `then` */
.finally( final => console.log('final: ' + final) )
;
opinions?
if you hit four false calls, you wait 10 seconds and should avoid Las Vegas and Atlantic City.
nothing wrong with the promises i am using, we need a different promise depending on the outcome of the previous result. i only [re]used the trueFalse example just as a simple example.
also, it was sort of fun, in a strange sort of way.
the pseudocode looks like this:
if parent row exists
then
return parent row id
else
create new parent and return the new parent row id
end-if
if child row exists (using parent row id from previous step)
return child row id
else
create child row and return child row id
end if
As you can see there are four functions: getParent, createParent, getChild, and createChild.
these four functions are actually FeathersJs functions. each function looks almost identical:
async function getParent(query) {
return await feathersApp.service('parent-table').find(query) ;
}
its tempting to just have one FeathersJs function and pass in the āservice-nameā (in this example, āparent-tableā) as an additional parm.
side-note: the more i use FeathersJs the more i love it. FeathersJs generate statement takes mere seconds to create a new table service.