Before the initial then
callback is triggered, the loop will have already completed. This is one of the promises' guarantees if the create
operation returns a proper promise rather than just a thenable that completes asynchronously.
To sequentially add ingredients (one at a time), you can utilize the reduce
trick; any promise rejection during this process will skip the remaining ingredients:
savedata.ingredients.split(',').reduce(function(p, ing) {
return p.then(function() {
var d = {
content_name: ing,
dogFoodId: dogId
};
return db.dog_ingredients.create(d);
});
}, Promise.resolve())
.catch(function(e) {
console.log(e);
res.status(403).send('Error');
return Promise.reject(e);
});
The code may appear lengthy due to comments and object initialization, but it can also be simplified as follows (if rejection propagation is not necessary):
savedata.ingredients.split(',').reduce(function(p, ing) {
return p.then(function() {
return db.dog_ingredients.create({ content_name: ing, dogFoodId: dogId });
});
}, Promise.resolve())
.catch(function(e) {
res.status(403).send('Error');
});
(While it's possible to further minimize the code, I prefer maintaining readability for easier debugging—leave minification to tools designed for that purpose.)
If adding ingredients in parallel is preferred, the code would be simpler:
Promise.all(savedata.ingredients.split(',').map(function(ing) {
return db.dog_ingredients.create({ content_name: ing, dogFoodId: dogId });
}).catch(function(e) {
res.status(403).send('Error');
return Promise.reject(e);
});
(Assuming there is no need to propagate the rejection in this case.)
However, keep in mind that this approach involves parallel processing.