I have a shallow understanding of JavaScript Promise and promise chain. Say, I have a method as shown below. It's written is TypeScript, but could be modified to match JavaScript ES6
private InsertPersonInDB(p : Person) {
return this.db.find({ //<- would this return?
selector: {objType: 'Person'},
fields: ['_id'],
sort: ['_id']
}).then( result => {
let allpersondIds : string[] = [];
(result.docs).forEach(rec => {
allpersondIds.push(rec._id);
});
return allpersondIds;
}).then ( allpersonIdsInDB => {
var id = this.getIdfromPersonName(person.personName, allpersonIdsInDB);
person._id = id;
return this.db.post(person) //<- or would this return?
}
}
//Calling function
for(let person of this.persons) {
InsertPersonInDB(person).then(result => {
console.log(result)
//Some UI updates
}).catch(err => {
console.log(err)
//Some UI updates notifying user about failure
});
}
Here, I have two return, first is
return this.db.find
which find function is a promise
and end of the then chain returns
return this.db.post(person)
even post function is a promise.
Here, I have three questions
1) When this function executes, what would return?
2) If the function immediately returns the promise, when would the chain thens execute?
2) What are better approaches to refactored the promise chain in a layered application. E.g. Few chain then needs to be executed in the service, other needs to be executed in UI, how do I structure my promises code?
The then() method returns a Promise . It takes up to two arguments: callback functions for the fulfilled and rejected cases of the Promise .
It is the fetch() function that returns a value, which is a Promise instance. It is the Promise instance on which you call the then() method, passing in a callback function, which will be eventually be fired when the async code finishes (and internally, calls resolve() ).
Await expressions make promise-returning functions behave as though they're synchronous by suspending execution until the returned promise is fulfilled or rejected. The resolved value of the promise is treated as the return value of the await expression.
First of all, I think you can easily test our your questions by just making some small examples for yourself. When I am unclear about how things work, I find it very useful to create a small example to just try out and see what happens. Lets do that for this question as well (see also https://plnkr.co/edit/K18o4Lp2jtUincjyG5wi?p=preview for the working version; open the console to see the results!):
function test() {
return returnPromise().then((value) => {
console.log('1st then, inside test(): ' + value);
return 'Hello';
}).then((value) => {
console.log('2nd then, inside test(): ' + value);
return 'world';
});
}
function returnPromise() {
return new Promise(function(resolve, reject) {
resolve('start of new Promise');
});
}
test().then((value) => {
console.log('3rd then, after calling test: ' + value);
});
For your questions:
then
functions. If you add another then
to the returned Promise, it will be added at the end of the chain. That is what you see when we are doing test().then(...)
. returnPromise
. Here we return a new Promise. The body of the Promise calls the resolve
method when it is done (in this case that is instantly), triggering the Promise to resolve and execute all then
methods chained to the Promise. Usually the Promise won't resolve instantly, but will perform an async task (e.g. retrieving data from a server) first. 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