2016-02-29 69 views
12

我目前正在構建一個Nodejs,Express,Sequelize(w PostgreSQL)應用程序,並遇到一些使用promise和事務和循環的問題。在Sequelize事務中使用循環和承諾

我想弄清楚如何在事務中使用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); 
     }); 

回答

19

您應該使用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 sequelize交易中,因爲我覺得它跳出來捕捉對交易

對不起格式化。在移動。

Promise.all將等待所有的承諾,在運行。然後返回之前(或失敗),而.then回調將是每個陣列

+0

感謝您的回答,但我得到一個錯誤告訴我,我需要將一個承諾鏈返回到事務。試圖在每個Promise.all之前添加「return」,但隨後我得到_「未處理的拒絕提交已在此事務中調用(fc7be023-1980-455e-9934-7816420daa2b),您不能再使用它」_ – ReturnToZero

+1

是的,它缺少一個回報,並沒有任何東西被推到userPromises。 –

+0

@BenjaminGruenbaum謝謝我昨天在移動設備上完成了這個任務,並且從來沒有機會回來檢查它。我會在更新後,我可以 – Datsik

4

的所有承諾的數據,您需要使用內置的循環結構藍鳥的附帶的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 
+0

同時工作和非常優雅的代碼。無法獲得'.nodeify(err);'工作。它說錯誤沒有定義。之前沒有使用過nodeify,所以我可能錯過了一些東西。 – ReturnToZero

+0

應該nodeify(next) - 對不起 –

0

第一: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); 
     } 
    }); 
    }); 
} 
+0

歡迎來到堆棧溢出,謝謝你提供一個答案。請查看:https://stackoverflow.com/help/how-to-answer – Daniel