循环后续集继续事务

时间:2018-01-05 15:20:50

标签: javascript express transactions sequelize.js

我在事务链代码中有多个循环,但在循环完成后,事务立即提交链而不继续下一个查询。我的代码是这样的:

        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){
        })
     }) 

那么如何在循环之后进行事务转到下一个循环?

1 个答案:

答案 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
  })