循环将在第一then
触发回调之前;这是承诺的保证之一(假设create
操作返回一个合适的承诺,而不仅仅是一个可承诺的;或者至少它的返回值异步完成)。
您可以使用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');
});
(或者你甚至可以变得更小,但对我来说调试遭受 —休假缩小文件到minifier。)
我假设你不想加入平行的成分,因为你已经表示要停止对“第一”的错误。但是,如果你这样做了,代码会更简单:
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);
});
(假设我们不需要传播排斥)
此外,虽然,这是平行的。
试图混合同步和异步代码只会导致流泪。 – Adam
你想结束循环吗?或者因为错误而结束整个脚本? –
那么,一般来说,除非链接它们,否则不会破坏异步操作循环。是的,您可以设置一个标志,然后在每个步骤中对该标志进行查询 - 但该标志只会在下一堆命令中进行检查。 – raina77ow