我在事务链代码中有多个循环,但在循环完成后,事务立即提交链而不继续下一个查询。我的代码是这样的:
return sm.sequelize.transaction(function (t) {
return Room.create({
room_type: req.body.room_type
},{transaction: t}).then(function(roomtype){
for (i=0;i<room.length;i++){
return Roomtype.create({
name : req.body.roomtype[i]
},{transaction: t}); //my transaction only work untill here and commit after that
}
for (i=0;i<another.length;i++){ //I need to continue my query to second loop here
return User.create({
email :req.body.email[i]
},{transaction:t});
}
}).then(function(result){
}).catch (function(err){
})
})
那么如何在循环之后进行事务转到下一个循环?
答案 0 :(得分:1)
请记住,只要您使用return
语句,该功能就会结束。不会再运行for
循环的迭代,第二循环也不会。你需要这样做而不必在循环中间返回。
只要交易顺序不重要,最好的方法是使用Promise.all
,它接受一系列承诺,一旦它们全部返回所有结果的结果完成。保留上面的其余逻辑,它看起来像这样:
return Room.create({
room_type: req.body.room_type
}, { transaction: t })
.then(function (roomtype) {
const promises = []
for (let i = 0; i < room.length; i++) {
const promise = Roomtype.create({
name : req.body.roomtype[i]
}, { transaction: t })
promises.push(promise)
}
for (let i = 0; i < another.length; i++){
const promise = User.create({
email :req.body.email[i]
}, { transaction: t })
promises.push(promise)
}
return Promise.all(promises)
})
.then(function (results) {
. . .
})
我会更进一步,用map
替换for循环。这不是绝对必要的,但会清理你的代码:
return Room.create({ room_type: req.body.room_type }, { transaction: t })
.then(function (roomtype) {
return Promise.all(req.body.roomtype.map(function (type) {
return Roomtype.create({ name: type }, { transaction: t })
}))
})
.then(function (roomResults) {
// Do the same thing for creating users here
})
或者,如果订单 很重要,那么您可能需要执行类似递归函数的操作,该函数将按顺序遍历每个Promise。
const createRooms = function (transaction, types, index = 0) {
return Roomtype.create({ name: types[index] }, { transaction })
.then(function (result) {
if (index < types.length - 1) {
return createRooms(transaction, types, index + 1)
}
return result
})
}
然后,您将在代码中调用该函数:
return Room.create({ room_type: req.body.room_type }, { transaction: t })
.then(function (roomtype) {
return createRooms(t, req.body.roomtype)
})
.then(function (result) {
// Do the same thing for creating Users here
})