Reputation: 11
Iam doing a vary basic promise demo code. Can anybody please explain me the reason why the followng code block gives undefined? Any help would be highky appreciated.
This is my promise Definition code. I have created three functions each returning a promise. For now, iam using setTimeout in the example
// promise-definitions.js
const definitions = {
getUser : (id) => {
return new Promise((resolve, reject) => {
setTimeout(()=> {
console.log('Getting User data...');
resolve({id: id, userName: 'Shamik Roy'})
}, 2000);
})
},
getRepos : (user) => {
return new Promise((resolve, reject) => {
setTimeout(()=> {
console.log('Getting repositories List...');
resolve(['repo1', 'repo2']);
}, 2000);
});
},
getCommits: (repoId) => {
return new Promise((resolve, reject) => {
setTimeout(()=>{
console.log('Getting commit List...');
resolve([{ id: 1, commit: "First Commit"},{ id:2, commit: "Second Commit"}]);
}, 2000);
})
}
module.exports = definitions;
// promise-consumer.js The following approach gives undefined in this line : console.log('Repository Data', repos);
const promise = require('./promise-definitions');
promise.getUser(10)
.then((user)=> {
console.log('User Data', user);
promise.getRepos(user.userName);
})
.then((repos) => {
console.log('Repository Data', repos);
promise.getCommits(repos[0]);
})
.then(commits => {
console.log('Commits', commits)
})
However the follwing approach works fine:
const promise = require('./promise-definitions');
promise.getUser(10)
.then((user)=> {
console.log('User Data', user);
return promise.getRepos(user.userName);
})
.then((repos) => {
console.log('Repository Data', repos);
return promise.getCommits(repos[0]);
})
.then(commits => {
console.log('Commits', commits)
})
Iam using a return statement when calling the individual promises and it is working fine.Can anyone please point out the reason for this.
Upvotes: 0
Views: 625
Reputation: 707716
Can anyone please point out the reason for this.
At the highest level, it's simply because this is how promise chains are designed to work. When you implement it the way they are designed to work, you get an expected result. When you don't, you don't get the result you want.
A .then()
handler on a promise chain just calls its callback and looks at the return value. If you supply a callback that returns nothing or returns a non-promise, then the promise chain just keeps right on going. The .then()
infrastructure has NO idea at all what's going on inside the callback you supplied. It has no magic powers to know you started some asynchronous operation inside your .then()
handler that it should magically wait for. Instead, the ONLY way it knows to wait for something to finish is if you return a promise from the .then()
handler. This is how promises are designed.
In your first example, you call some function that returns a promise, but because you don't return the promise from the .then()
handler, the parent promise chain does not know anything about your new promise.
You have effectively just created a new branched promise chain that is not connected in any way to the original one. This new promise chain proceeds on its own schedule and does not affect the original promise chain in any way.
In your second code block, you return the new promise from the .then()
handler. That properly inserts that new promise into the existing promise chain and the parent promise chains waits for that newly returned promise to fulfill before proceeding with the rest of its chain. This is, obviously, how you properly chain promises together.
Upvotes: 1