CaseyB CaseyB - 3 years ago 46
Javascript Question

Spawning Multiple Promises

I'm not sure this is possible but this is what I'm trying to do. I have a call to a database that returns a promise. In the

then
I want to iterate over the results and spawn a new promise for each row to make an HTTP request. It's performing all of the HTTP requests but I am not able to chain a then for each request. Here's what I have tried:

Attempt 1

userDao.getBitbucketInfoForUser(token.id, cohortId)
// Get Bitbucket information and make clones
.then((teams) => {
for(const team of teams) {
console.log('Clone repo ' + sourceRepo + ' for Team-' + team.teamNumber);
return makeFork(gitInfo, sourceRepo, team);
}
})
.then((result) => {
const team = result.team;
console.log('Wait for Team ' + team + ' repo');
})
.catch((error) => {
console.log(error);
response.status(error.status).json(error).end()
});


I realized right away that this was dumb because I was returning and breaking out of my loop. So I went to this:

Attempt 2

userDao.getBitbucketInfoForUser(token.id, cohortId)
// Get Bitbucket information and make clones
.then((teams) => {
for(const team of teams) {
console.log('Clone repo ' + sourceRepo + ' for Team-' + team.teamNumber);
makeFork(gitInfo, sourceRepo, team)
.then((result) => Promise.resolve(result));
}
})
.then((result) => {
const team = result.team;
console.log('Wait for Team ' + team + ' repo');
})
.catch((error) => {
console.log(error);
response.status(error.status).json(error).end()
});


This time it went through and made all of the calls in
makeFork
but only ran the
then
once. Next I tried this:

Attempt 3

userDao.getBitbucketInfoForUser(token.id, cohortId)
// Get Bitbucket information and make clones
.then((teams) => {
for(const team of teams) {
console.log('Clone repo ' + sourceRepo + ' for Team-' + team.teamNumber);
new Promise((resolve, reject) => resolve(makeFork(gitInfo, sourceRepo, team)));
}
})
.then((result) => {
const team = result.team;
console.log('Wait for Team ' + result + ' repo');
})
.catch((error) => {
console.log(error);
response.status(error.status).json(error).end()
});


This resulted in the exact same behavior as Attempt 2. Is there a way to do what I want?

Answer Source

You're close. As noted by other users Promise.all is exactly what you want, even if you need to act on each element individually.

userDao.getBitbucketInfoForUser(token.id, cohortId)
    // Get Bitbucket information and make clones
    .then((teams) => {
        // Act on each element individually.
        const teamPromises = teams.map((team) => {
            return makeFork(gitInfo, sourceRepo, team).then((result) => {
                const team = result.team;
                console.log('Wait for Team ' + team + ' repo');
            });
        });
        // Then resolve everything.
        return Promise.all(teamPromises);
    })
    .catch((error) => {
        console.log(error);
        response.status(error.status).json(error).end()
    });
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download