我目前正在构建一个Nodejs,Express,Sequelize(w.PostgreSQL)应用程序,并且在使用promises以及事务和循环时遇到了一些问题。
我试图弄清楚如何在事务中使用for循环。我试图循环遍历成员列表并在数据库中为每个成员创建一个新用户。
我知道以下代码是错误的,但它显示了我想要做的事情。
有人能指出我正确的方向吗?
{{1}}
答案 0 :(得分:28)
您应该使用Promise.all
var members = req.body.members;
models.sequelize.transaction(function (t) {
var promises = []
for (var i = 0; i < members.length; i++) {
var newPromise = models.User.create({'firstname':members[i], 'email':members[i], 'pending':true}, {transaction: t});
promises.push(newPromise);
};
return Promise.all(promises).then(function(users) {
var userPromises = [];
for (var i = 0; i < users.length; i++) {
userPromises.push(users[i].addInvitations([group], {transaction: t});
}
return Promise.all(userPromises);
});
}).then(function (result) {
console.log("YAY");
}).catch(function (err) {
console.log("NO!!!");
return next(err);
});
我不相信你需要catch
在续集交易中,因为我认为它跳出了交易的捕获
抱歉格式化。在移动。
Promise.all会在运行.then之前等待所有promises返回(或失败),.then
回调将是每个数组的所有promise数据
答案 1 :(得分:5)
你需要使用bluebird的内置循环结构,它带有sequelize:
var members = req.body.members;
models.sequelize.transaction(t =>
Promise.map(members, m => // create all users
models.User.create({firstname: m, email: m, 'pending':true}, {transaction: t})
).map(user => // then for each user add the invitation
user.addInvitations([group], {transaction: t}) // add invitations
)).nodeify(err); // convert to node err-back syntax for express
答案 2 :(得分:1)
这取决于您的Node.js实现。我使用express,POSTGRES和sequelize进行了相同的设置。
我个人更喜欢async / await(ES6)实现,而不是then / catch,因为它更易于阅读。另外,创建一个可以在外部调用的函数可以提高可重用性。
async function createMemeber(req) {
let members = req.body.members;
for (var i = 0; i < members.length; i++) {
// Must be defined inside loop but outside the try to reset for each new member;
let transaction = models.sequelize.transaction();
try {
// Start transaction block.
let user = await models.User.create({'firstname':members[i], 'email':members[i], 'pending':true}, {transaction});
await user.addInvitations([group], {transaction}));
// if successful commit the record. Else in the catch block rollback the record.
transaction.commit();
// End transaction block.
return user;
} catch (error) {
console.log("An unexpected error occurred creating user record: ", error);
transaction.rollback();
// Throw the error back to the caller and handle it there. i.e. the called express route.
throw error;
}
}
}
答案 3 :(得分:0)
首先:https://caolan.github.io/async/docs.html
所以,很容易:
File imageFile = File(Environment.getExternalStorageDirectory(), "myimage.jpg");
答案 4 :(得分:0)
如果有人正在寻找使用 async 和 await 的 typescript v4.0.5 的解决方案,那么这对我来说很有效。也许你也可以在你的 javascript 应用程序中使用它,但这取决于它的版本。
const array = ['one','two','three'];
const createdTransaction = sequelize.transaction();
const promises = array.map(async item => {
await model.create({
name: item,
},
{ transaction: createdTransaction },
);
});
Promise.all(promises).then(async values => {
await createdTransaction.commit();
});