var ing_data = savedata.ingredients.split(',');
for(var i =0; i<ing_data.length; i++){
var d = {
content_name: ing_data[i],
dogFoodId: dogId
}
db.dog_ingredients.create(d).then(function(data){
}, function(e){
console.log(e);
res.status(403).send('Error');
//break for loop this point
});
}
如何在承诺中打破循环?
我正在使用node express,sequelize module
答案 0 :(得分:2)
在触发第一个then
回调之前,循环将结束;这是promises的保证之一(假设create
操作返回一个正确的promise,而不仅仅是一个thenable;或者至少它返回的thenable异步完成)。
你可以使用reduce
技巧循环添加连续这些成分(一次一个);一路上的承诺拒绝会跳过剩下的成分:
savedata.ingredients.split(',').reduce(function(p, ing) {
// Chain this ingredient on the end of the promise, return
// the new promise `then` returns, which gets passed to the
// next iteration
return p.then(function() {
var d = {
content_name: ing,
dogFoodId: dogId
};
// Return the promise from `create`
return db.dog_ingredients.create(d);
});
}, Promise.resolve()/* Seeds the loop above */)
.catch(function(e) {
// We got a rejection, which bypasses any pending resolution
// handlers we set up above; process the rejection.
console.log(e);
res.status(403).send('Error');
return Promise.reject(e); // Only need to propgate the rejection like this
// this if something will use the return value of
// this overall structure
});
看起来很大,但主要是注释和对象初始化器;我们也可以这样写(假设我们不需要传播拒绝):
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');
});
(或者你甚至可以变小,但对我来说,调试会受到影响 - 让缩小到缩小器。)
我假设您不想并行添加成分,因为您已表明要停止“第一个”错误。但如果你这样做,代码会更简单:
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);
});
(假设我们不需要传播拒绝。)
但是,这是平行的。