在 Sequelize 的交易中使用循环和承诺
Using loops and promises in transactions in Sequelize
我目前正在构建一个Nodejs,Express,Sequelize(w. PostgreSQL)应用程序,并且在将promise与事务和循环一起使用时遇到了一些问题。
我正在尝试弄清楚如何在事务中使用 for 循环。我正在尝试遍历成员列表,并在数据库中为每个成员创建一个新用户。
我知道以下代码是错误的,但它显示了我正在尝试做什么。
谁能指出我正确的方向?
var members = req.body.members;
models.sequelize.transaction(function (t) {
for (var i = 0; i < members.length; i++) {
return models.User.create({'firstname':members[i], 'email':members[i], 'pending':true}, {transaction: t}).then(function(user) {
return user.addInvitations([group], {transaction: t}).then(function(){}).catch(function(err){return next(err);});
})
};
}).then(function (result) {
console.log("YAY");
}).catch(function (err) {
console.log("NO!!!");
return next(err);
});
你应该使用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 之前等待所有承诺返回(或失败),.then
回调将是每个数组中的所有 promise 数据
你需要使用蓝鸟的内置循环结构,它附带续集:
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(next); // convert to node err-back syntax for express
根据您对 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;
}
}
}
如果有人正在寻找使用异步和等待的打字稿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();
});
第一:https://caolan.github.io/async/docs.html
因此,很容易:
// requiring...
const async = require('async');
// exports...
createAllAsync: (array, transaction) => {
return new Promise((resolve, reject) => {
var results = [];
async.forEachOf(array, (elem, index, callback) => {
results.push(models.Model.create(elem, {transaction}));
callback();
}, err => {
if (err) {
reject(err);
}
else {
resolve(results);
}
});
});
}
相关文章:
- 等待循环调用的所有承诺完成
- 而循环使用蓝鸟承诺
- 蓝鸟承诺循环
- javascript承诺在循环中或如何逐个调用函数
- 循环中的承诺问题
- 转换嵌套'对于'循环成一个承诺,为了一个承诺?嵌套承诺
- 在循环中解析所有承诺后返回值
- 从 foreach 循环链接承诺
- 链接在webdriver.io中的while循环中承诺
- 循环超出范围,不执行承诺链
- 在nodejs中使用Q.js承诺进行循环的正确方法
- 如何仅从循环中调用最后的承诺
- 同时循环承诺,直到另一个承诺结束
- AngularJS:app.run() 中的承诺永远陷入循环
- JavaScript ES6 承诺在 while 循环中调用异步操作
- JavaScript循环承诺在参数中使用数组进行迭代
- Javascript for循环承诺
- Angular JS循环承诺
- 打破循环/承诺并从函数返回
- 无限期地循环承诺,直到被拒绝