を使用しています。これは約束の保証の1つです(create
オペレーションは、単に返すことができない、または返されるthenableが非同期に完了することを前提としています)。
reduce
トリックを使用して、これらの成分をループさせることができます。(1度に1つ);途中で約束を拒否すると、残りの成分は飛び越されます:
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