循環將在第一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